github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/syz-cluster/pkg/db/series_repo_test.go (about)

     1  // Copyright 2024 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package db
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestSeriesRepositoryGet(t *testing.T) {
    14  	client, ctx := NewTransientDB(t)
    15  	repo := NewSeriesRepository(client)
    16  	series := &Series{
    17  		ExtID:       "ext-id",
    18  		AuthorName:  "Name1 Name2",
    19  		AuthorEmail: "some@email.com",
    20  		Title:       "something",
    21  		Version:     2,
    22  		PublishedAt: time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC),
    23  		Cc:          []string{"email"},
    24  	}
    25  	patches := []*Patch{
    26  		{
    27  			Title:   "first patch",
    28  			Seq:     1,
    29  			Link:    "first link",
    30  			BodyURI: "gcs://patch1",
    31  		},
    32  		{
    33  			Title:   "second patch",
    34  			Seq:     2,
    35  			Link:    "second link",
    36  			BodyURI: "gcs://patch2",
    37  		},
    38  	}
    39  	err := repo.Insert(ctx, series, func() ([]*Patch, error) {
    40  		return patches, nil
    41  	})
    42  	assert.NoError(t, err)
    43  	// Check that we obtain the exact object from the DB.
    44  	series2, err := repo.GetByID(ctx, series.ID)
    45  	assert.NoError(t, err)
    46  	assert.EqualValues(t, series, series2)
    47  	// Compare the patches.
    48  	patches2, err := repo.ListPatches(ctx, series)
    49  	assert.NoError(t, err)
    50  	assert.EqualValues(t, patches, patches2)
    51  }
    52  
    53  func TestSeriesRepositoryList(t *testing.T) {
    54  	client, ctx := NewTransientDB(t)
    55  	repo := NewSeriesRepository(client)
    56  	for _, series := range []*Series{
    57  		{
    58  			ExtID:       "series-3",
    59  			Title:       "Series 3",
    60  			PublishedAt: time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC),
    61  			Cc:          []string{"a"},
    62  		},
    63  		{
    64  			ExtID:       "series-1",
    65  			Title:       "Series 1",
    66  			PublishedAt: time.Date(2020, time.January, 1, 1, 0, 0, 0, time.UTC),
    67  			Cc:          []string{"a", "b"},
    68  		},
    69  		{
    70  			ExtID:       "series-2",
    71  			Title:       "Series 2",
    72  			PublishedAt: time.Date(2020, time.January, 1, 2, 0, 0, 0, time.UTC),
    73  			Cc:          []string{"c"},
    74  		},
    75  	} {
    76  		err := repo.Insert(ctx, series, func() ([]*Patch, error) { return nil, nil })
    77  		assert.NoError(t, err)
    78  	}
    79  
    80  	t.Run("count", func(t *testing.T) {
    81  		count, err := repo.Count(ctx)
    82  		assert.NoError(t, err)
    83  		assert.Equal(t, 3, count)
    84  	})
    85  
    86  	t.Run("all", func(t *testing.T) {
    87  		list, err := repo.ListLatest(ctx, SeriesFilter{}, time.Time{})
    88  		assert.NoError(t, err)
    89  		assert.Len(t, list, 3)
    90  	})
    91  
    92  	t.Run("with_limit", func(t *testing.T) {
    93  		list, err := repo.ListLatest(ctx, SeriesFilter{
    94  			Limit: 2,
    95  		}, time.Time{})
    96  		assert.NoError(t, err)
    97  		assert.Len(t, list, 2)
    98  		assert.Equal(t, "Series 3", list[0].Series.Title)
    99  		assert.Equal(t, "Series 2", list[1].Series.Title)
   100  	})
   101  
   102  	t.Run("with_offset", func(t *testing.T) {
   103  		list, err := repo.ListLatest(ctx, SeriesFilter{
   104  			Limit:  1,
   105  			Offset: 1,
   106  		}, time.Time{})
   107  		assert.NoError(t, err)
   108  		assert.Len(t, list, 1)
   109  		assert.Equal(t, "Series 2", list[0].Series.Title)
   110  	})
   111  
   112  	t.Run("with_from", func(t *testing.T) {
   113  		// Skips the latest series.
   114  		list, err := repo.ListLatest(ctx, SeriesFilter{}, time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC))
   115  		assert.NoError(t, err)
   116  		assert.Len(t, list, 2)
   117  		assert.Equal(t, "Series 2", list[0].Series.Title)
   118  		assert.Equal(t, "Series 1", list[1].Series.Title)
   119  	})
   120  
   121  	t.Run("filter_by_cc", func(t *testing.T) {
   122  		list, err := repo.ListLatest(ctx, SeriesFilter{Cc: "a"}, time.Time{})
   123  		assert.NoError(t, err)
   124  		assert.Len(t, list, 2)
   125  	})
   126  
   127  	// Start one session to test filtering by status.
   128  	series2, err := repo.GetByExtID(ctx, "series-2")
   129  	assert.NoError(t, err)
   130  
   131  	dtd := &dummyTestData{t, ctx, client}
   132  	session := dtd.dummySession(series2)
   133  	dtd.addSessionTest(session, "test")
   134  	t.Run("filter_status_waiting", func(t *testing.T) {
   135  		list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusWaiting}, time.Time{})
   136  		assert.NoError(t, err)
   137  		assert.Len(t, list, 1)
   138  	})
   139  
   140  	dtd.startSession(session)
   141  	t.Run("filter_status_in_progress", func(t *testing.T) {
   142  		list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusInProgress}, time.Time{})
   143  		assert.NoError(t, err)
   144  		assert.Len(t, list, 1)
   145  	})
   146  
   147  	dtd.addSessionTest(session, "test")
   148  	finding := dtd.addFinding(session, "title", "test")
   149  	dtd.finishSession(session)
   150  	t.Run("query_finding_count", func(t *testing.T) {
   151  		list, err := repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusFinished}, time.Time{})
   152  		assert.NoError(t, err)
   153  		assert.Len(t, list, 1)
   154  		assert.Equal(t, 1, list[0].Findings, "there must be just one finding")
   155  	})
   156  
   157  	t.Run("query_with_findings", func(t *testing.T) {
   158  		list, err := repo.ListLatest(ctx, SeriesFilter{WithFindings: true}, time.Time{})
   159  		assert.NoError(t, err)
   160  		assert.Len(t, list, 1)
   161  		assert.Equal(t, "Series 2", list[0].Series.Title)
   162  	})
   163  
   164  	dtd.invalidateFinding(finding)
   165  	t.Run("invalidated_findings", func(t *testing.T) {
   166  		list, err := repo.ListLatest(ctx, SeriesFilter{WithFindings: true}, time.Time{})
   167  		assert.NoError(t, err)
   168  		assert.Len(t, list, 0)
   169  		// When not filtered, ensure invalidated findings are not counted in.
   170  		list, err = repo.ListLatest(ctx, SeriesFilter{Status: SessionStatusFinished}, time.Time{})
   171  		assert.NoError(t, err)
   172  		assert.Len(t, list, 1)
   173  		assert.Equal(t, 0, list[0].Findings)
   174  	})
   175  }
   176  
   177  func TestSeriesRepositoryUpdate(t *testing.T) {
   178  	client, ctx := NewTransientDB(t)
   179  	repo := NewSeriesRepository(client)
   180  	series := &Series{
   181  		ExtID:       "ext-id",
   182  		AuthorName:  "Name1 Name2",
   183  		AuthorEmail: "some@email.com",
   184  		Title:       "something",
   185  		Version:     2,
   186  		PublishedAt: time.Date(2020, time.January, 1, 3, 0, 0, 0, time.UTC),
   187  		Cc:          []string{"email"},
   188  	}
   189  	err := repo.Insert(ctx, series, func() ([]*Patch, error) {
   190  		return nil, nil
   191  	})
   192  	assert.NoError(t, err)
   193  	// Update the object.
   194  	err = repo.Update(ctx, series.ID, func(series *Series) error {
   195  		series.Title = "updated title"
   196  		return nil
   197  	})
   198  	assert.NoError(t, err)
   199  	// Check that the entity has been updated.
   200  	series2, err := repo.GetByID(ctx, series.ID)
   201  	assert.NoError(t, err)
   202  	assert.Equal(t, "updated title", series2.Title)
   203  }