Skip to content

Commit 7a693da

Browse files
SarahFrenchradeksimko
authored andcommitted
[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 6322501 commit 7a693da

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
@@ -1537,7 +1537,7 @@ func (p *GRPCProvider) ReadStateBytes(r providers.ReadStateBytesRequest) (resp p
15371537
return resp
15381538
}
15391539

1540-
var buf *bytes.Buffer
1540+
buf := &bytes.Buffer{}
15411541
var expectedTotalLength int
15421542
for {
15431543
chunk, err := client.Recv()
@@ -1546,7 +1546,7 @@ func (p *GRPCProvider) ReadStateBytes(r providers.ReadStateBytesRequest) (resp p
15461546
break
15471547
}
15481548
if err != nil {
1549-
resp.Diagnostics = resp.Diagnostics.Append(err)
1549+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
15501550
break
15511551
}
15521552
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(chunk.Diagnostics))
@@ -1603,39 +1603,52 @@ func (p *GRPCProvider) WriteStateBytes(r providers.WriteStateBytesRequest) (resp
16031603
// TODO: Configurable chunk size
16041604
chunkSize := 4 * 1_000_000 // 4MB
16051605

1606-
if len(r.Bytes) < chunkSize {
1606+
client, err := p.client.WriteStateBytes(ctx)
1607+
if err != nil {
1608+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1609+
return resp
1610+
}
1611+
1612+
buf := bytes.NewBuffer(r.Bytes)
1613+
var totalLength int64 = int64(len(r.Bytes))
1614+
var totalBytesProcessed int
1615+
for {
1616+
chunk := buf.Next(chunkSize)
1617+
1618+
if len(chunk) == 0 {
1619+
// The previous iteration read the last of the data. Now we finish up.
1620+
protoResp, err := client.CloseAndRecv()
1621+
if err != nil {
1622+
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1623+
return resp
1624+
}
1625+
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
1626+
if resp.Diagnostics.HasErrors() {
1627+
return resp
1628+
}
1629+
break
1630+
}
1631+
1632+
// There is more data to write
16071633
protoReq := &proto6.WriteStateBytes_RequestChunk{
16081634
TypeName: r.TypeName,
16091635
StateId: r.StateId,
1610-
Bytes: r.Bytes,
1611-
TotalLength: int64(len(r.Bytes)),
1636+
Bytes: chunk,
1637+
TotalLength: totalLength,
16121638
Range: &proto6.StateRange{
1613-
Start: 0,
1614-
End: int64(len(r.Bytes)),
1639+
Start: int64(totalBytesProcessed),
1640+
End: int64(totalBytesProcessed + len(chunk)),
16151641
},
16161642
}
1617-
client, err := p.client.WriteStateBytes(ctx)
1618-
if err != nil {
1619-
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1620-
return resp
1621-
}
16221643
err = client.Send(protoReq)
16231644
if err != nil {
16241645
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
16251646
return resp
16261647
}
1627-
protoResp, err := client.CloseAndRecv()
1628-
if err != nil {
1629-
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
1630-
return resp
1631-
}
1632-
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
1633-
if resp.Diagnostics.HasErrors() {
1634-
return resp
1635-
}
1636-
}
16371648

1638-
// TODO: implement chunking for state files larger than chunkSize
1649+
// Track progress before next iteration
1650+
totalBytesProcessed += len(chunk)
1651+
}
16391652

16401653
return resp
16411654
}

0 commit comments

Comments
 (0)