github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/export_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"testing"
    13  
    14  	"github.com/masterhung0112/hk_server/v5/model"
    15  	"github.com/masterhung0112/hk_server/v5/utils/fileutils"
    16  
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestListExports(t *testing.T) {
    21  	th := Setup(t)
    22  	defer th.TearDown()
    23  
    24  	t.Run("no permissions", func(t *testing.T) {
    25  		exports, resp := th.Client.ListExports()
    26  		require.NotNil(t, resp.Error)
    27  		require.Equal(t, "api.context.permissions.app_error", resp.Error.Id)
    28  		require.Nil(t, exports)
    29  	})
    30  
    31  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
    32  		exports, resp := c.ListExports()
    33  		require.Nil(t, resp.Error)
    34  		require.Empty(t, exports)
    35  	}, "no exports")
    36  
    37  	dataDir, found := fileutils.FindDir("data")
    38  	require.True(t, found)
    39  
    40  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
    41  		exportDir := filepath.Join(dataDir, *th.App.Config().ExportSettings.Directory)
    42  		err := os.Mkdir(exportDir, 0700)
    43  		require.NoError(t, err)
    44  		defer os.RemoveAll(exportDir)
    45  
    46  		f, err := os.Create(filepath.Join(exportDir, "export.zip"))
    47  		require.NoError(t, err)
    48  		f.Close()
    49  
    50  		exports, resp := c.ListExports()
    51  		require.Nil(t, resp.Error)
    52  		require.Len(t, exports, 1)
    53  		require.Equal(t, exports[0], "export.zip")
    54  	}, "expected exports")
    55  
    56  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
    57  		value := *th.App.Config().ExportSettings.Directory
    58  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExportSettings.Directory = value + "new" })
    59  		defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExportSettings.Directory = value })
    60  
    61  		exportDir := filepath.Join(dataDir, value+"new")
    62  		err := os.Mkdir(exportDir, 0700)
    63  		require.NoError(t, err)
    64  		defer os.RemoveAll(exportDir)
    65  
    66  		exports, resp := c.ListExports()
    67  		require.Nil(t, resp.Error)
    68  		require.Empty(t, exports)
    69  
    70  		f, err := os.Create(filepath.Join(exportDir, "export.zip"))
    71  		require.NoError(t, err)
    72  		f.Close()
    73  
    74  		exports, resp = c.ListExports()
    75  		require.Nil(t, resp.Error)
    76  		require.Len(t, exports, 1)
    77  		require.Equal(t, "export.zip", exports[0])
    78  	}, "change export directory")
    79  }
    80  
    81  func TestDeleteExport(t *testing.T) {
    82  	th := Setup(t)
    83  	defer th.TearDown()
    84  
    85  	t.Run("no permissions", func(t *testing.T) {
    86  		ok, resp := th.Client.DeleteExport("export.zip")
    87  		require.NotNil(t, resp.Error)
    88  		require.Equal(t, "api.context.permissions.app_error", resp.Error.Id)
    89  		require.False(t, ok)
    90  	})
    91  
    92  	dataDir, found := fileutils.FindDir("data")
    93  	require.True(t, found)
    94  	exportDir := filepath.Join(dataDir, *th.App.Config().ExportSettings.Directory)
    95  
    96  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
    97  		err := os.Mkdir(exportDir, 0700)
    98  		require.NoError(t, err)
    99  		defer os.RemoveAll(exportDir)
   100  		exportName := "export.zip"
   101  		f, err := os.Create(filepath.Join(exportDir, exportName))
   102  		require.NoError(t, err)
   103  		f.Close()
   104  
   105  		exports, resp := c.ListExports()
   106  		require.Nil(t, resp.Error)
   107  		require.Len(t, exports, 1)
   108  		require.Equal(t, exports[0], exportName)
   109  
   110  		ok, resp := c.DeleteExport(exportName)
   111  		require.Nil(t, resp.Error)
   112  		require.True(t, ok)
   113  
   114  		exports, resp = c.ListExports()
   115  		require.Nil(t, resp.Error)
   116  		require.Empty(t, exports)
   117  
   118  		// verify idempotence
   119  		ok, resp = c.DeleteExport(exportName)
   120  		require.Nil(t, resp.Error)
   121  		require.True(t, ok)
   122  	}, "successfully delete export")
   123  }
   124  
   125  func TestDownloadExport(t *testing.T) {
   126  	th := Setup(t)
   127  	defer th.TearDown()
   128  
   129  	t.Run("no permissions", func(t *testing.T) {
   130  		var buf bytes.Buffer
   131  		n, resp := th.Client.DownloadExport("export.zip", &buf, 0)
   132  		require.NotNil(t, resp.Error)
   133  		require.Equal(t, "api.context.permissions.app_error", resp.Error.Id)
   134  		require.Zero(t, n)
   135  	})
   136  
   137  	dataDir, found := fileutils.FindDir("data")
   138  	require.True(t, found)
   139  	exportDir := filepath.Join(dataDir, *th.App.Config().ExportSettings.Directory)
   140  
   141  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   142  		var buf bytes.Buffer
   143  		n, resp := c.DownloadExport("export.zip", &buf, 0)
   144  		require.NotNil(t, resp.Error)
   145  		require.Equal(t, "api.export.export_not_found.app_error", resp.Error.Id)
   146  		require.Zero(t, n)
   147  	}, "not found")
   148  
   149  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   150  		err := os.Mkdir(exportDir, 0700)
   151  		require.NoError(t, err)
   152  		defer os.RemoveAll(exportDir)
   153  
   154  		data := randomBytes(t, 1024*1024)
   155  		var buf bytes.Buffer
   156  		exportName := "export.zip"
   157  		err = ioutil.WriteFile(filepath.Join(exportDir, exportName), data, 0600)
   158  		require.NoError(t, err)
   159  
   160  		n, resp := c.DownloadExport(exportName, &buf, 0)
   161  		require.Nil(t, resp.Error)
   162  		require.Equal(t, len(data), int(n))
   163  		require.Equal(t, data, buf.Bytes())
   164  	}, "full download")
   165  
   166  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
   167  		err := os.Mkdir(exportDir, 0700)
   168  		require.NoError(t, err)
   169  		defer os.RemoveAll(exportDir)
   170  
   171  		data := randomBytes(t, 1024*1024)
   172  		var buf bytes.Buffer
   173  		exportName := "export.zip"
   174  		err = ioutil.WriteFile(filepath.Join(exportDir, exportName), data, 0600)
   175  		require.NoError(t, err)
   176  
   177  		offset := 1024 * 512
   178  		n, resp := c.DownloadExport(exportName, &buf, int64(offset))
   179  		require.Nil(t, resp.Error)
   180  		require.Equal(t, len(data)-offset, int(n))
   181  		require.Equal(t, data[offset:], buf.Bytes())
   182  	}, "download with offset")
   183  }
   184  
   185  func BenchmarkDownloadExport(b *testing.B) {
   186  	th := Setup(b)
   187  	defer th.TearDown()
   188  
   189  	dataDir, found := fileutils.FindDir("data")
   190  	require.True(b, found)
   191  	exportDir := filepath.Join(dataDir, *th.App.Config().ExportSettings.Directory)
   192  
   193  	err := os.Mkdir(exportDir, 0700)
   194  	require.NoError(b, err)
   195  	defer os.RemoveAll(exportDir)
   196  
   197  	exportName := "export.zip"
   198  	f, err := os.Create(filepath.Join(exportDir, exportName))
   199  	require.NoError(b, err)
   200  	f.Close()
   201  
   202  	err = os.Truncate(filepath.Join(exportDir, exportName), 1024*1024*1024)
   203  	require.NoError(b, err)
   204  
   205  	b.ResetTimer()
   206  	for i := 0; i < b.N; i++ {
   207  		outFilePath := filepath.Join(dataDir, fmt.Sprintf("export%d.zip", i))
   208  		outFile, _ := os.Create(outFilePath)
   209  		th.SystemAdminClient.DownloadExport(exportName, outFile, 0)
   210  		outFile.Close()
   211  		os.Remove(outFilePath)
   212  	}
   213  }