Skip to content

Commit

Permalink
Added test for corrupted scrape
Browse files Browse the repository at this point in the history
  • Loading branch information
naman47vyas committed Apr 8, 2024
1 parent b1eedaa commit ec09de8
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
21 changes: 16 additions & 5 deletions receiver/mysqlreceiver/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package mysqlreceiver // import "github.com/open-telemetry/opentelemetry-collect

import (
"database/sql"
"errors"
"fmt"
"regexp"
"strconv"
Expand Down Expand Up @@ -219,16 +220,26 @@ func (c *mySQLClient) getInnodbStats() (map[string]string, error) {
}

func ExtractInnodbTotalLargeMemoryAllocated(statusText string) (int64, error) {
re := regexp.MustCompile(`Total large memory allocated (\d+)`)
// fmt.Println(statusText)
re := regexp.MustCompile(`Total large memory allocated (-?\d+)`)
matches := re.FindStringSubmatch(statusText)
fmt.Println("matches: ", matches)
if len(matches) < 2 {
return 0, fmt.Errorf("could not find 'Total large memory allocated' in the status output")
return -1, fmt.Errorf("could not find 'Total large memory allocated' in the status output")
}
totalMemoryAllocated, err := strconv.Atoi(matches[1])
totalLargeMemoryAllocated, err := strconv.Atoi(matches[1])
if err != nil {
return 0, fmt.Errorf("failed to convert 'Total large memory allocated' value to int: %v", err)
return -1, fmt.Errorf("failed to convert 'Total large memory allocated' value to int: %v", err)
}
return int64(totalMemoryAllocated), nil
const systemTotalMemory int64 = 1 << 40 // 1 TB of memory.

if int64(totalLargeMemoryAllocated) < 0 {
return -1, errors.New("invalid memory allocation: 'Total Large Memory Allocated' value is negative, which is not possible")
} else if int64(totalLargeMemoryAllocated) > systemTotalMemory {
return -1, fmt.Errorf("invalid memory allocation: 'Total Large Memory Allocated' value exceeds the system's total memory capacity of %d bytes", systemTotalMemory)
}

return int64(totalLargeMemoryAllocated), nil
}

func (c *mySQLClient) getInnodbStatus() (int64, error) {
Expand Down
3 changes: 3 additions & 0 deletions receiver/mysqlreceiver/scraper.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ func (m *mySQLScraper) scrapeInnodbStatus(now pcommon.Timestamp, errs *scraperer
errs.Add(err)
}
m.mb.RecordMysqlInnodbMemTotalDataPoint(now, int64(totalLargeMemoryAllocated))
// rb := m.mb.NewResourceBuilder()
// rb.SetMysqlInstanceEndpoint(m.config.Endpoint)
// m.mb.EmitForResource(metadata.WithResource(rb.Emit()))
}

func (m *mySQLScraper) scrapeGlobalStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
Expand Down
48 changes: 45 additions & 3 deletions receiver/mysqlreceiver/scraper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"database/sql"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -122,9 +123,42 @@ func TestScrape(t *testing.T) {
require.True(t, errors.As(scrapeErr, &partialError), "returned error was not PartialScrapeError")
// 5 comes from 4 failed "must-have" metrics that aren't present,
// and the other failure comes from a row that fails to parse as a number
fmt.Println("Failed partial errors ", partialError.Failed)
require.Equal(t, partialError.Failed, 5, "Expected partial error count to be 5")
})

t.Run("scrape is getting corrupted value", func(t *testing.T) {
cfg := createDefaultConfig().(*Config)
cfg.Username = "otel"
cfg.Password = "otel"
cfg.NetAddr = confignet.NetAddr{Endpoint: "localhost:3306"}

cfg.MetricsBuilderConfig.Metrics.MysqlInnodbMemTotal.Enabled = true

scraper := newMySQLScraper(receivertest.NewNopCreateSettings(), cfg)
scraper.sqlclient = &mockClient{
innodbStatusFile: "innodb_status_corrupted",
}

actualMetrics, scrapeErr := scraper.scrape(context.Background())
require.Error(t, scrapeErr)
fmt.Print("actual error -----------", scrapeErr)

expectedFile := filepath.Join("testdata", "scraper", "expected_corrupted_innodb_mem-total.yaml")
expectedMetrics, err := golden.ReadMetrics(expectedFile)
fmt.Print("\nexpected error ---------", err)

require.NoError(t, err)
assert.NoError(t, pmetrictest.CompareMetrics(actualMetrics, expectedMetrics,
pmetrictest.IgnoreMetricDataPointsOrder(), pmetrictest.IgnoreStartTimestamp(),
pmetrictest.IgnoreTimestamp(),
))

var corruptedError scrapererror.PartialScrapeError
require.True(t, errors.As(scrapeErr, &corruptedError), "returned error was not PartialScrapeError")
require.Equal(t, corruptedError.Failed, 98, "Expected corrupted error count to be 98")
})

}

var _ client = (*mockClient)(nil)
Expand All @@ -146,17 +180,25 @@ func (c *mockClient) getInnodbStatus() (int64, error) {
if err != nil {
return -1, err
}

totalLargeMemoryAllocate, err := ExtractInnodbTotalLargeMemoryAllocated(innodbStatus)
fmt.Println("Scrapping mock file----------------------------------------------------")
totalLargeMemoryAllocated, err := ExtractInnodbTotalLargeMemoryAllocated(innodbStatus)
const systemTotalMemory int64 = 1 << 40 // 1 TB of memory.
if err != nil {
return -1, err
}
if totalLargeMemoryAllocated < 0 {
return -1, errors.New("invalid memory allocation: 'Total Large Memory Allocated' value is negative, which is not possible")
} else if totalLargeMemoryAllocated > systemTotalMemory {
return -1, fmt.Errorf("invalid memory allocation: 'Total Large Memory Allocated' value exceeds the system's total memory capacity of %d bytes", systemTotalMemory)
}

return totalLargeMemoryAllocate, nil
fmt.Println("Total Large mem allocated: ", totalLargeMemoryAllocated)
return totalLargeMemoryAllocated, nil
}

func readFileToString(fname string) (string, error) {
content, err := os.ReadFile(filepath.Join("testdata", "scraper", fname+".txt"))
fmt.Println("file being scrapped is :", fname)
if err != nil {
return "", err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resourceMetrics:
- resource:
attributes:
- key: mysql.instance.endpoint
value:
stringValue: localhost:3306
scopeMetrics:
- metrics:
- description: Total memory used by InnoDB, as shown in the BUFFER POOL AND MEMORY section of SHOW ENGINE INNODB STATUS.
name: mysql.innodb.mem_total
gauge:
dataPoints:
- asInt: "-1"
startTimeUnixNano: "1000000"
timeUnixNano: "2000000"
unit: By
scope:
name: otelcol/mysqlreceiver
version: latest


0 comments on commit ec09de8

Please sign in to comment.