github.com/richardwilkes/toolbox@v1.121.0/xio/fs/safe/file_test.go (about)

     1  // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, version 2.0. If a copy of the MPL was not distributed with
     5  // this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  //
     7  // This Source Code Form is "Incompatible With Secondary Licenses", as
     8  // defined by the Mozilla Public License, version 2.0.
     9  
    10  package safe_test
    11  
    12  import (
    13  	"os"
    14  	"path/filepath"
    15  	"testing"
    16  
    17  	"github.com/richardwilkes/toolbox/check"
    18  	"github.com/richardwilkes/toolbox/xio/fs/safe"
    19  )
    20  
    21  func TestAbortNonExisting(t *testing.T) {
    22  	tmpdir, err := os.MkdirTemp("", "safe_test_")
    23  	check.NoError(t, err)
    24  	defer removeAll(t, tmpdir)
    25  	filename := filepath.Join(tmpdir, "abort.txt")
    26  	var f *safe.File
    27  	f, err = safe.CreateWithMode(filename, 0o600)
    28  	check.NoError(t, err)
    29  	var n int
    30  	n, err = f.WriteString("abort")
    31  	check.NoError(t, err)
    32  	check.Equal(t, 5, n)
    33  	check.NoError(t, f.Close())
    34  	_, err = os.Stat(filename)
    35  	check.Error(t, err)
    36  }
    37  
    38  func removeAll(t *testing.T, path string) {
    39  	t.Helper()
    40  	check.NoError(t, os.RemoveAll(path))
    41  }
    42  
    43  func TestCommitNonExisting(t *testing.T) {
    44  	tmpdir, err := os.MkdirTemp("", "safe_test_")
    45  	check.NoError(t, err)
    46  	defer removeAll(t, tmpdir)
    47  	filename := filepath.Join(tmpdir, "commit.txt")
    48  	var f *safe.File
    49  	f, err = safe.CreateWithMode(filename, 0o600)
    50  	check.NoError(t, err)
    51  	var n int
    52  	n, err = f.WriteString("commit")
    53  	check.NoError(t, err)
    54  	check.Equal(t, 6, n)
    55  	check.NoError(t, f.Commit())
    56  	check.NoError(t, f.Close())
    57  	_, err = os.Stat(filename)
    58  	check.NoError(t, err)
    59  	check.NoError(t, os.Remove(filename))
    60  }
    61  
    62  func TestAbortExisting(t *testing.T) {
    63  	tmpdir, err := os.MkdirTemp("", "safe_test_")
    64  	check.NoError(t, err)
    65  	defer removeAll(t, tmpdir)
    66  	filename := filepath.Join(tmpdir, "safe.txt")
    67  	originalData := []byte("safe")
    68  	check.NoError(t, os.WriteFile(filename, originalData, 0o600))
    69  	var f *safe.File
    70  	f, err = safe.CreateWithMode(filename, 0o600)
    71  	check.NoError(t, err)
    72  	var n int
    73  	n, err = f.WriteString("bad")
    74  	check.NoError(t, err)
    75  	check.Equal(t, 3, n)
    76  	err = f.Close()
    77  	check.NoError(t, err)
    78  	var data []byte
    79  	data, err = os.ReadFile(filename)
    80  	check.NoError(t, err)
    81  	check.Equal(t, originalData, data)
    82  	check.NoError(t, os.Remove(filename))
    83  }
    84  
    85  func TestCommitExisting(t *testing.T) {
    86  	tmpdir, err := os.MkdirTemp("", "safe_test_")
    87  	check.NoError(t, err)
    88  	defer removeAll(t, tmpdir)
    89  	filename := filepath.Join(tmpdir, "safe.txt")
    90  	originalData := []byte("safe")
    91  	replacement := []byte("replaced")
    92  	check.NoError(t, os.WriteFile(filename, originalData, 0o600))
    93  	var f *safe.File
    94  	f, err = safe.CreateWithMode(filename, 0o600)
    95  	check.NoError(t, err)
    96  	var n int
    97  	n, err = f.Write(replacement)
    98  	check.NoError(t, err)
    99  	check.Equal(t, len(replacement), n)
   100  	check.NoError(t, f.Commit())
   101  	check.NoError(t, f.Close())
   102  	var data []byte
   103  	data, err = os.ReadFile(filename)
   104  	check.NoError(t, err)
   105  	check.Equal(t, replacement, data)
   106  	check.NoError(t, os.Remove(filename))
   107  }