github.com/Jeffail/benthos/v3@v3.65.0/lib/test/integration/cassandra_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/Jeffail/benthos/v3/internal/integration"
    11  	"github.com/gocql/gocql"
    12  	"github.com/ory/dockertest/v3"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  var _ = registerIntegrationTest("cassandra", func(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	pool, err := dockertest.NewPool("")
    21  	require.NoError(t, err)
    22  
    23  	pool.MaxWait = time.Second * 60
    24  	resource, err := pool.Run("cassandra", "latest", nil)
    25  	require.NoError(t, err)
    26  	t.Cleanup(func() {
    27  		assert.NoError(t, pool.Purge(resource))
    28  	})
    29  
    30  	var session *gocql.Session
    31  	t.Cleanup(func() {
    32  		if session != nil {
    33  			session.Close()
    34  		}
    35  	})
    36  
    37  	resource.Expire(900)
    38  	require.NoError(t, pool.Retry(func() error {
    39  		if session == nil {
    40  			conn := gocql.NewCluster(fmt.Sprintf("localhost:%v", resource.GetPort("9042/tcp")))
    41  			conn.Consistency = gocql.All
    42  			var rerr error
    43  			if session, rerr = conn.CreateSession(); rerr != nil {
    44  				return rerr
    45  			}
    46  		}
    47  		session.Query(
    48  			"CREATE KEYSPACE testspace WITH replication = {'class':'SimpleStrategy','replication_factor':1};",
    49  		).Exec()
    50  		return session.Query(
    51  			"CREATE TABLE testspace.testtable (id int primary key, content text, created_at timestamp);",
    52  		).Exec()
    53  	}))
    54  
    55  	t.Run("with JSON", func(t *testing.T) {
    56  		template := `
    57  output:
    58    cassandra:
    59      addresses:
    60        - localhost:$PORT
    61      query: 'INSERT INTO testspace.table$ID JSON ?'
    62      args_mapping: 'root = [ this ]'
    63  `
    64  		queryGetFn := func(ctx context.Context, testID, messageID string) (string, []string, error) {
    65  			var resID int
    66  			var resContent string
    67  			if err := session.Query(
    68  				fmt.Sprintf("select id, content from testspace.table%v where id = ?;", testID), messageID,
    69  			).Scan(&resID, &resContent); err != nil {
    70  				return "", nil, err
    71  			}
    72  			return fmt.Sprintf(`{"content":"%v","id":%v}`, resContent, resID), nil, err
    73  		}
    74  		suite := integration.StreamTests(
    75  			integration.StreamTestOutputOnlySendSequential(10, queryGetFn),
    76  			integration.StreamTestOutputOnlySendBatch(10, queryGetFn),
    77  		)
    78  		suite.Run(
    79  			t, template,
    80  			integration.StreamTestOptPort(resource.GetPort("9042/tcp")),
    81  			integration.StreamTestOptSleepAfterInput(time.Second*10),
    82  			integration.StreamTestOptSleepAfterOutput(time.Second*10),
    83  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
    84  				vars.ID = strings.ReplaceAll(testID, "-", "")
    85  				require.NoError(t, session.Query(
    86  					fmt.Sprintf(
    87  						"CREATE TABLE testspace.table%v (id int primary key, content text, created_at timestamp);",
    88  						vars.ID,
    89  					),
    90  				).Exec())
    91  			}),
    92  		)
    93  	})
    94  
    95  	t.Run("with values", func(t *testing.T) {
    96  		template := `
    97  output:
    98    cassandra:
    99      addresses:
   100        - localhost:$PORT
   101      query: 'INSERT INTO testspace.table$ID (id, content, created_at, meows) VALUES (?, ?, ?, ?)'
   102      args_mapping: |
   103        root = [ this.id, this.content, now(), [ "first meow", "second meow" ] ]
   104  `
   105  		queryGetFn := func(ctx context.Context, testID, messageID string) (string, []string, error) {
   106  			var resID int
   107  			var resContent string
   108  			var createdAt time.Time
   109  			var meows []string
   110  			if err := session.Query(
   111  				fmt.Sprintf("select id, content, created_at, meows from testspace.table%v where id = ?;", testID), messageID,
   112  			).Scan(&resID, &resContent, &createdAt, &meows); err != nil {
   113  				return "", nil, err
   114  			}
   115  			if time.Since(createdAt) > time.Hour || time.Since(createdAt) < 0 {
   116  				return "", nil, fmt.Errorf("received bad created_at: %v", createdAt)
   117  			}
   118  			assert.Equal(t, []string{"first meow", "second meow"}, meows)
   119  			return fmt.Sprintf(`{"content":"%v","id":%v}`, resContent, resID), nil, err
   120  		}
   121  		suite := integration.StreamTests(
   122  			integration.StreamTestOutputOnlySendSequential(10, queryGetFn),
   123  			integration.StreamTestOutputOnlySendBatch(10, queryGetFn),
   124  		)
   125  		suite.Run(
   126  			t, template,
   127  			integration.StreamTestOptPort(resource.GetPort("9042/tcp")),
   128  			integration.StreamTestOptSleepAfterInput(time.Second*10),
   129  			integration.StreamTestOptSleepAfterOutput(time.Second*10),
   130  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   131  				vars.ID = strings.ReplaceAll(testID, "-", "")
   132  				require.NoError(t, session.Query(
   133  					fmt.Sprintf(
   134  						"CREATE TABLE testspace.table%v (id int primary key, content text, created_at timestamp, meows list<text>);",
   135  						vars.ID,
   136  					),
   137  				).Exec())
   138  			}),
   139  		)
   140  	})
   141  
   142  	t.Run("with old style values", func(t *testing.T) {
   143  		template := `
   144  output:
   145    cassandra:
   146      addresses:
   147        - localhost:$PORT
   148      query: 'INSERT INTO testspace.table$ID (id, content, created_at) VALUES (?, ?, ?)'
   149      args:
   150        - ${! json("id") }
   151        - ${! json("content") }
   152        - ${! timestamp("2006-01-02T15:04:05.999Z07:00") }
   153  `
   154  		queryGetFn := func(ctx context.Context, testID, messageID string) (string, []string, error) {
   155  			var resID int
   156  			var resContent string
   157  			var createdAt time.Time
   158  			if err := session.Query(
   159  				fmt.Sprintf("select id, content, created_at from testspace.table%v where id = ?;", testID), messageID,
   160  			).Scan(&resID, &resContent, &createdAt); err != nil {
   161  				return "", nil, err
   162  			}
   163  			if time.Since(createdAt) > time.Hour || time.Since(createdAt) < 0 {
   164  				return "", nil, fmt.Errorf("received bad created_at: %v", createdAt)
   165  			}
   166  			return fmt.Sprintf(`{"content":"%v","id":%v}`, resContent, resID), nil, err
   167  		}
   168  		suite := integration.StreamTests(
   169  			integration.StreamTestOutputOnlySendSequential(10, queryGetFn),
   170  			integration.StreamTestOutputOnlySendBatch(10, queryGetFn),
   171  		)
   172  		suite.Run(
   173  			t, template,
   174  			integration.StreamTestOptPort(resource.GetPort("9042/tcp")),
   175  			integration.StreamTestOptSleepAfterInput(time.Second*10),
   176  			integration.StreamTestOptSleepAfterOutput(time.Second*10),
   177  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   178  				vars.ID = strings.ReplaceAll(testID, "-", "")
   179  				require.NoError(t, session.Query(
   180  					fmt.Sprintf(
   181  						"CREATE TABLE testspace.table%v (id int primary key, content text, created_at timestamp);",
   182  						vars.ID,
   183  					),
   184  				).Exec())
   185  			}),
   186  		)
   187  	})
   188  })