123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
// Copyright 2026 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package objstore_test
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
|
|
. "github.com/pingcap/tidb/pkg/objstore"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestBatched(t *testing.T) {
|
|
ctx := context.Background()
|
|
bat := Batch(nil) // Passing nil as we don't need actual storage operations
|
|
|
|
// Test operations
|
|
operations := []struct {
|
|
name string
|
|
op func() error
|
|
expected []Effect
|
|
}{
|
|
{
|
|
name: "DeleteFiles",
|
|
op: func() error {
|
|
return bat.DeleteFiles(ctx, []string{"file1.txt", "file2.txt"})
|
|
},
|
|
expected: []Effect{EffDeleteFiles{Files: []string{"file1.txt", "file2.txt"}}},
|
|
},
|
|
{
|
|
name: "DeleteFile",
|
|
op: func() error {
|
|
return bat.DeleteFile(ctx, "file3.txt")
|
|
},
|
|
expected: []Effect{EffDeleteFile("file3.txt")},
|
|
},
|
|
{
|
|
name: "WriteFile",
|
|
op: func() error {
|
|
return bat.WriteFile(ctx, "file4.txt", []byte("content"))
|
|
},
|
|
expected: []Effect{EffPut{File: "file4.txt", Content: []byte("content")}},
|
|
},
|
|
{
|
|
name: "Rename",
|
|
op: func() error {
|
|
return bat.Rename(ctx, "oldName.txt", "newName.txt")
|
|
},
|
|
expected: []Effect{EffRename{From: "oldName.txt", To: "newName.txt"}},
|
|
},
|
|
{
|
|
name: "SequenceOfOperations",
|
|
op: func() error {
|
|
if err := bat.DeleteFile(ctx, "file5.txt"); err != nil {
|
|
return err
|
|
}
|
|
if err := bat.WriteFile(ctx, "file6.txt", []byte("new content")); err != nil {
|
|
return err
|
|
}
|
|
return bat.Rename(ctx, "file6.txt", "fileRenamed.txt")
|
|
},
|
|
expected: []Effect{
|
|
EffDeleteFile("file5.txt"),
|
|
EffPut{File: "file6.txt", Content: []byte("new content")},
|
|
EffRename{From: "file6.txt", To: "fileRenamed.txt"},
|
|
}},
|
|
}
|
|
|
|
for _, op := range operations {
|
|
t.Run(op.name, func(t *testing.T) {
|
|
require.NoError(t, op.op())
|
|
|
|
effects := bat.ReadOnlyEffects()
|
|
require.Equal(t, len(op.expected), len(effects))
|
|
for i, effect := range effects {
|
|
require.Equal(t, op.expected[i], effect)
|
|
}
|
|
|
|
// Reset effects for the next test
|
|
bat.CleanEffects()
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONEffects(t *testing.T) {
|
|
effects := []Effect{
|
|
EffPut{File: "example.txt", Content: []byte("Hello, world")},
|
|
EffDeleteFiles{Files: []string{"old_file.txt", "temp.txt"}},
|
|
EffDeleteFile("obsolete.txt"),
|
|
EffRename{From: "old_name.txt", To: "new_name.txt"},
|
|
}
|
|
|
|
tmp, err := SaveJSONEffectsToTmp(effects)
|
|
require.NoError(t, err)
|
|
f, err := os.Open(tmp)
|
|
require.NoError(t, err)
|
|
buf, err := io.ReadAll(f)
|
|
require.NoError(t, err)
|
|
|
|
expectedJSON := `[
|
|
{"type":"objstore.EffPut","effect":{"file":"example.txt","content":"SGVsbG8sIHdvcmxk"}},
|
|
{"type":"objstore.EffDeleteFiles","effect":{"files":["old_file.txt","temp.txt"]}},
|
|
{"type":"objstore.EffDeleteFile","effect":"obsolete.txt"},
|
|
{"type":"objstore.EffRename","effect":{"from":"old_name.txt","to":"new_name.txt"}}
|
|
]`
|
|
|
|
require.JSONEq(t, expectedJSON, string(buf), "Output JSON should match expected JSON")
|
|
}
|