Skip to content

Commit bd2039e

Browse files
authored
[WIP] - Testing ReadStateBytes and WriteStateBytes (#37464)
* Fix nil pointer error * Add WIP test for ReadStateBytes * Move test mock to separate testing file * Update mock to send unexpected EOF when there's a problem returning data and it's not a true EOF * Add test case for when length != expected length * Add test for when trying to read state from a store type that doesn't exist * Change symbol names to lowercase * Add ability to force a diagnostic to be returned from `mockReadStateBytesClient`'s `Recv` method * Add test showing error diagnostics raised by the ReadStateBytes client are returned * Add missing header * Simplify mock by using an embedded type * Rename `mockOpts` to `mockReadStateBytesOpts` * Update existing tests to assert what arguments are passed to the RPC method call * Add mock WriteStateBytesClient which uses `go.uber.org/mock/gomock` to enable assertions about calls to Send * Add a test for WriteStateBytes that makes assertions about calls to the Send method * Update test case to explicitly test writing data smaller than the chunk size * Implement chunking in WriteStateBytes, add test case to assert expected chunking behaviour * Add generated mock for Provider_WriteStateBytesClient in protocol v6 * Update tests to use new `MockProvider_WriteStateBytesClient`, remove handwritten mock * Update code comments in test * Add tests for diagnostics and errors returned during WriteStateBytes * Add generated mock for Provider_ReadStateBytesClient in protocol v6, replace old mock * Add test case for grpc errors in ReadStateBytes, fix how error is returned * Typo in comment * Add missing warning test, rename some test cases
1 parent 74fd3bc commit bd2039e

File tree

4 files changed

+899
-26
lines changed

4 files changed

+899
-26
lines changed

internal/plugin6/grpc_provider.go

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ func (p *GRPCProvider) ReadStateBytes(r providers.ReadStateBytesRequest) (resp p
15101510
return resp
15111511
}
15121512

1513-
var buf *bytes.Buffer
1513+
buf := &bytes.Buffer{}
15141514
var expectedTotalLength int
15151515
for {
15161516
chunk, err := client.Recv()
@@ -1519,7 +1519,7 @@ func (p *GRPCProvider) ReadStateBytes(r providers.ReadStateBytesRequest) (resp p
15191519
break
15201520
}
15211521
if err != nil {
1522-
resp.Diagnostics = resp.Diagnostics.Append(err)
1522+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
15231523
break
15241524
}
15251525
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(chunk.Diagnostics))
@@ -1576,39 +1576,52 @@ func (p *GRPCProvider) WriteStateBytes(r providers.WriteStateBytesRequest) (resp
15761576
// TODO: Configurable chunk size
15771577
chunkSize := 4 * 1_000_000 // 4MB
15781578

1579-
if len(r.Bytes) < chunkSize {
1579+
client, err := p.client.WriteStateBytes(ctx)
1580+
if err != nil {
1581+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1582+
return resp
1583+
}
1584+
1585+
buf := bytes.NewBuffer(r.Bytes)
1586+
var totalLength int64 = int64(len(r.Bytes))
1587+
var totalBytesProcessed int
1588+
for {
1589+
chunk := buf.Next(chunkSize)
1590+
1591+
if len(chunk) == 0 {
1592+
// The previous iteration read the last of the data. Now we finish up.
1593+
protoResp, err := client.CloseAndRecv()
1594+
if err != nil {
1595+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1596+
return resp
1597+
}
1598+
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
1599+
if resp.Diagnostics.HasErrors() {
1600+
return resp
1601+
}
1602+
break
1603+
}
1604+
1605+
// There is more data to write
15801606
protoReq := &proto6.WriteStateBytes_RequestChunk{
15811607
TypeName: r.TypeName,
15821608
StateId: r.StateId,
1583-
Bytes: r.Bytes,
1584-
TotalLength: int64(len(r.Bytes)),
1609+
Bytes: chunk,
1610+
TotalLength: totalLength,
15851611
Range: &proto6.StateRange{
1586-
Start: 0,
1587-
End: int64(len(r.Bytes)),
1612+
Start: int64(totalBytesProcessed),
1613+
End: int64(totalBytesProcessed + len(chunk)),
15881614
},
15891615
}
1590-
client, err := p.client.WriteStateBytes(ctx)
1591-
if err != nil {
1592-
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1593-
return resp
1594-
}
15951616
err = client.Send(protoReq)
15961617
if err != nil {
15971618
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
15981619
return resp
15991620
}
1600-
protoResp, err := client.CloseAndRecv()
1601-
if err != nil {
1602-
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1603-
return resp
1604-
}
1605-
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
1606-
if resp.Diagnostics.HasErrors() {
1607-
return resp
1608-
}
1609-
}
16101621

1611-
// TODO: implement chunking for state files larger than chunkSize
1622+
// Track progress before next iteration
1623+
totalBytesProcessed += len(chunk)
1624+
}
16121625

16131626
return resp
16141627
}

0 commit comments

Comments
 (0)