[MM-57693] Add schema dump to Support Packet (#31162)
Co-authored-by: Claude <noreply@anthropic.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
824d3b8259
Коммит
04a60b6609
@@ -26,6 +26,7 @@ func (a *App) GenerateSupportPacket(rctx request.CTX, options *model.SupportPack
|
||||
"jobs": a.getSupportPacketJobList,
|
||||
"permissions": a.getSupportPacketPermissionsInfo,
|
||||
"plugins": a.getPluginsFile,
|
||||
"schema": a.getSupportPacketDatabaseSchema,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -375,3 +376,24 @@ func (a *App) getSupportPacketMetadata(_ request.CTX) (*model.FileData, error) {
|
||||
}
|
||||
return fileData, nil
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketDatabaseSchema(rctx request.CTX) (*model.FileData, error) {
|
||||
if *a.Config().SqlSettings.DriverName != model.DatabaseDriverPostgres {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
schemaInfo, err := a.Srv().Store().GetSchemaDefinition()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get schema definition")
|
||||
}
|
||||
|
||||
schemaDump, err := yaml.Marshal(schemaInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal schema into YAML")
|
||||
}
|
||||
|
||||
return &model.FileData{
|
||||
Filename: "database_schema.yaml",
|
||||
Body: schemaDump,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -77,6 +77,11 @@ func TestGenerateSupportPacket(t *testing.T) {
|
||||
"goroutines",
|
||||
}
|
||||
|
||||
// database_schema.yaml is only generated for Postgres
|
||||
if *th.App.Config().SqlSettings.DriverName == model.DatabaseDriverPostgres {
|
||||
expectedFileNames = append(expectedFileNames, "database_schema.yaml")
|
||||
}
|
||||
|
||||
expectedFileNamesWithLogs := append(expectedFileNames, []string{
|
||||
"mattermost.log",
|
||||
"notifications.log",
|
||||
@@ -143,6 +148,9 @@ func TestGenerateSupportPacket(t *testing.T) {
|
||||
mockStore.On("TotalMasterDbConnections").Return(30)
|
||||
mockStore.On("TotalReadDbConnections").Return(20)
|
||||
mockStore.On("TotalSearchDbConnections").Return(10)
|
||||
mockStore.On("GetSchemaDefinition").Return(&model.SupportPacketDatabaseSchema{
|
||||
Tables: []model.DatabaseTable{},
|
||||
}, nil)
|
||||
|
||||
oldStore := th.App.Srv().Store()
|
||||
t.Cleanup(func() {
|
||||
@@ -687,3 +695,98 @@ func TestGetSupportPacketMetadata(t *testing.T) {
|
||||
assert.NotEmpty(t, metadate.GeneratedAt)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetSupportPacketDatabaseSchema(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
// Mock store for testing
|
||||
mockStore := &smocks.Store{}
|
||||
originalStore := th.App.Srv().Store()
|
||||
th.App.Srv().SetStore(mockStore)
|
||||
defer th.App.Srv().SetStore(originalStore)
|
||||
// Set up mock return for schema definition
|
||||
mockStore.On("GetSchemaDefinition").Return(&model.SupportPacketDatabaseSchema{
|
||||
Tables: []model.DatabaseTable{
|
||||
{
|
||||
Name: "users",
|
||||
Columns: []model.DatabaseColumn{
|
||||
{Name: "id", DataType: "varchar", IsNullable: false},
|
||||
{Name: "username", DataType: "varchar", IsNullable: false},
|
||||
{Name: "email", DataType: "varchar", IsNullable: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "channels",
|
||||
Columns: []model.DatabaseColumn{
|
||||
{Name: "id", DataType: "varchar", IsNullable: false},
|
||||
{Name: "name", DataType: "varchar", IsNullable: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "teams",
|
||||
Columns: []model.DatabaseColumn{
|
||||
{Name: "id", DataType: "varchar", IsNullable: false},
|
||||
{Name: "name", DataType: "varchar", IsNullable: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "posts",
|
||||
Columns: []model.DatabaseColumn{
|
||||
{Name: "id", DataType: "varchar", IsNullable: false},
|
||||
{Name: "message", DataType: "text", IsNullable: false},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
// Test with Postgres
|
||||
oldDriverName := *th.App.Config().SqlSettings.DriverName
|
||||
*th.App.Config().SqlSettings.DriverName = model.DatabaseDriverPostgres
|
||||
defer func() {
|
||||
*th.App.Config().SqlSettings.DriverName = oldDriverName
|
||||
}()
|
||||
|
||||
fileData, err := th.App.getSupportPacketDatabaseSchema(th.Context)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, fileData)
|
||||
assert.Equal(t, "database_schema.yaml", fileData.Filename)
|
||||
assert.Positive(t, len(fileData.Body))
|
||||
|
||||
var schema model.SupportPacketDatabaseSchema
|
||||
err = yaml.Unmarshal(fileData.Body, &schema)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify schema structure
|
||||
assert.NotEmpty(t, schema.Tables)
|
||||
|
||||
// Verify that common tables are present
|
||||
tableNames := make([]string, 0, len(schema.Tables))
|
||||
for _, table := range schema.Tables {
|
||||
tableNames = append(tableNames, table.Name)
|
||||
}
|
||||
|
||||
// Verify some core tables
|
||||
expectedTables := []string{"users", "channels", "teams", "posts"}
|
||||
for _, expected := range expectedTables {
|
||||
assert.Contains(t, tableNames, expected)
|
||||
}
|
||||
|
||||
// Verify table structure
|
||||
for _, table := range schema.Tables {
|
||||
if table.Name == "users" {
|
||||
// Check user table has key columns
|
||||
columnNames := make([]string, 0, len(table.Columns))
|
||||
for _, column := range table.Columns {
|
||||
columnNames = append(columnNames, column.Name)
|
||||
}
|
||||
|
||||
expectedColumns := []string{"id", "username", "email"}
|
||||
for _, expected := range expectedColumns {
|
||||
assert.Contains(t, columnNames, expected)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user