Skip to content

Commit

Permalink
fix multi-document yaml reading errors (#2322)
Browse files Browse the repository at this point in the history
Signed-off-by: Maxwell <[email protected]>
  • Loading branch information
maxwell-can-not-fly authored May 7, 2024
1 parent 005f904 commit f4f89c5
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 5 deletions.
15 changes: 10 additions & 5 deletions pkg/application/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ package application

import (
"bytes"
"errors"
"fmt"
"io"
"os"
"path/filepath"

Expand Down Expand Up @@ -77,15 +79,18 @@ func (m mergeProcessor) Process(appRoot string) error {

logrus.Debugf("will do merge processor on the file : %s", target)

contents, err := os.ReadFile(filepath.Clean(target))
f, err := os.Open(filepath.Clean(target))
if err != nil {
return err
}

for _, section := range bytes.Split(contents, []byte("---\n")) {
dec := yaml.NewDecoder(f)
for {
destDataMap := make(map[string]interface{})

err = yaml.Unmarshal(section, &destDataMap)
err = dec.Decode(destDataMap)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
return fmt.Errorf("failed to unmarshal config data: %v", err)
}
Expand All @@ -103,7 +108,7 @@ func (m mergeProcessor) Process(appRoot string) error {
result = append(result, out)
}

err = osUtils.NewCommonWriter(target).WriteFile(bytes.Join(result, []byte("---\n")))
err = osUtils.NewCommonWriter(target).WriteFile(bytes.Join(result, []byte("\n---\n")))
if err != nil {
return fmt.Errorf("failed to write to file %s with raw mode: %v", target, err)
}
Expand Down
94 changes: 94 additions & 0 deletions pkg/application/files_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright © 2023 Alibaba Group Holding Ltd.
//
// 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 application

import (
"os"
"path/filepath"
"testing"

"github.com/google/go-cmp/cmp"
v2 "github.com/sealerio/sealer/types/api/v2"
)

func Test_mergeProcessor_Process(t *testing.T) {
tests := []struct {
source string
patch string
expected string
wantErr bool
}{
{
source: "a: b\nb: c",
patch: "b: d",
expected: "a: b\nb: d\n",
wantErr: false,
},
{
source: "a: b\n## ---\nb: c",
patch: "b: d",
expected: "a: b\nb: d\n",
wantErr: false,
},
{
source: "a: b\n---\nb: c",
patch: "b: d",
expected: "a: b\nb: d\n\n---\nb: d\n",
wantErr: false,
},
}
// prepare a tmp dir to write test files
appRoot, err := os.MkdirTemp("", "sealer-unit-test")
if err != nil {
t.Fatal(err)
}
defer func() {
_ = os.RemoveAll(appRoot)
}()

testFile := filepath.Join(appRoot, "test.yaml")
for _, tt := range tests {
// prepare source file
f, err := os.Create(testFile)
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(tt.source)
if err != nil {
t.Fatal(err)
}

r := mergeProcessor{
AppFile: v2.AppFile{
Path: "test.yaml",
Strategy: v2.MergeStrategy,
Data: tt.patch,
},
}

if err := r.Process(appRoot); err != nil && !tt.wantErr {
t.Errorf("mergeProcessor.Process() error = %v", err)
} else {
output, err := os.ReadFile(testFile)
if err != nil {
t.Fatal(err)
}

if diff := cmp.Diff(string(output), tt.expected); diff != "" {
t.Errorf("test failed expected=%s; output=%s; diff=%s", tt.expected, string(output), diff)
}
}
}
}

0 comments on commit f4f89c5

Please sign in to comment.