mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-10 16:47:04 +02:00
Now default is not to follow the logs (which is similar to `kubectl logs`). Integration test was added for `Logs()` API and `osctl logs` command. Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
212 lines
4.9 KiB
Go
212 lines
4.9 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package file_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/talos-systems/talos/pkg/chunker/file"
|
|
)
|
|
|
|
type FileChunkerSuite struct {
|
|
suite.Suite
|
|
|
|
tmpDir string
|
|
no int
|
|
reader, writer *os.File
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) SetupSuite() {
|
|
var err error
|
|
|
|
suite.tmpDir, err = ioutil.TempDir("", "talos")
|
|
suite.Require().NoError(err)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) SetupTest() {
|
|
suite.no++
|
|
|
|
var err error
|
|
|
|
suite.writer, err = os.Create(filepath.Join(suite.tmpDir, fmt.Sprintf("%d.log", suite.no)))
|
|
suite.Require().NoError(err)
|
|
|
|
suite.reader, err = os.Open(suite.writer.Name())
|
|
suite.Require().NoError(err)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TearDownTest() {
|
|
suite.Require().NoError(suite.writer.Close())
|
|
suite.Require().NoError(suite.reader.Close())
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TearDownSuite() {
|
|
suite.Require().NoError(os.RemoveAll(suite.tmpDir))
|
|
}
|
|
|
|
func collectChunks(chunksCh <-chan []byte) <-chan []byte {
|
|
combinedCh := make(chan []byte)
|
|
|
|
go func() {
|
|
res := []byte(nil)
|
|
|
|
for chunk := range chunksCh {
|
|
res = append(res, chunk...)
|
|
}
|
|
|
|
combinedCh <- res
|
|
}()
|
|
|
|
return combinedCh
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TestStreaming() {
|
|
chunker := file.NewChunker(suite.reader, file.WithFollow())
|
|
|
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
|
defer ctxCancel()
|
|
|
|
chunksCh := chunker.Read(ctx)
|
|
combinedCh := collectChunks(chunksCh)
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("abc")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("def")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("ghi")
|
|
time.Sleep(50 * time.Millisecond)
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("jkl")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("mno")
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
ctxCancel()
|
|
|
|
suite.Require().Equal([]byte("abcdefghijklmno"), <-combinedCh)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TestStreamingWithSomeHead() {
|
|
chunker := file.NewChunker(suite.reader, file.WithFollow())
|
|
|
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
|
defer ctxCancel()
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("abc")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("def")
|
|
|
|
chunksCh := chunker.Read(ctx)
|
|
combinedCh := collectChunks(chunksCh)
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("ghi")
|
|
time.Sleep(50 * time.Millisecond)
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("jkl")
|
|
time.Sleep(50 * time.Millisecond)
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("mno")
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
ctxCancel()
|
|
|
|
suite.Require().Equal([]byte("abcdefghijklmno"), <-combinedCh)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TestStreamingSmallBuffer() {
|
|
chunker := file.NewChunker(suite.reader, file.WithSize(1), file.WithFollow())
|
|
|
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
|
defer ctxCancel()
|
|
|
|
chunksCh := chunker.Read(ctx)
|
|
combinedCh := collectChunks(chunksCh)
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("abc")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("def")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("ghi")
|
|
time.Sleep(50 * time.Millisecond)
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("jkl")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("mno")
|
|
|
|
// create extra file to try to confuse watch
|
|
_, err := os.Create(filepath.Join(suite.tmpDir, "x.log"))
|
|
suite.Require().NoError(err)
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
ctxCancel()
|
|
|
|
suite.Require().Equal([]byte("abcdefghijklmno"), <-combinedCh)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TestStreamingDeleted() {
|
|
chunker := file.NewChunker(suite.reader, file.WithFollow())
|
|
|
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
|
defer ctxCancel()
|
|
|
|
chunksCh := chunker.Read(ctx)
|
|
combinedCh := collectChunks(chunksCh)
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("abc")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("def")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("ghi")
|
|
time.Sleep(50 * time.Millisecond)
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("jkl")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("mno")
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
// chunker should terminate when file is removed
|
|
suite.Require().NoError(os.Remove(suite.writer.Name()))
|
|
|
|
suite.Require().Equal([]byte("abcdefghijklmno"), <-combinedCh)
|
|
}
|
|
|
|
func (suite *FileChunkerSuite) TestNoFollow() {
|
|
chunker := file.NewChunker(suite.reader)
|
|
|
|
ctx, ctxCancel := context.WithCancel(context.Background())
|
|
defer ctxCancel()
|
|
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("abc")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("def")
|
|
// nolint: errcheck
|
|
suite.writer.WriteString("ghi")
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
chunksCh := chunker.Read(ctx)
|
|
combinedCh := collectChunks(chunksCh)
|
|
|
|
suite.Require().Equal([]byte("abcdefghi"), <-combinedCh)
|
|
}
|
|
|
|
func TestFileChunkerSuite(t *testing.T) {
|
|
suite.Run(t, new(FileChunkerSuite))
|
|
}
|