From 9f4b346800dfea32e084a63b791a34d8295d1d36 Mon Sep 17 00:00:00 2001 From: Giselle van Dongen Date: Wed, 24 May 2023 12:31:34 +0200 Subject: [PATCH 1/3] Get state should be able to handler number 0 --- src/state_machine.ts | 13 ++-- test/get_state.test.ts | 144 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 5 deletions(-) diff --git a/src/state_machine.ts b/src/state_machine.ts index e584a713..951c0d26 100644 --- a/src/state_machine.ts +++ b/src/state_machine.ts @@ -173,7 +173,7 @@ export class DurableExecutionStateMachine implements RestateContext { this.incrementJournalIndex(); const msg = GetStateEntryMessage.create({ key: Buffer.from(name) }); - const promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.storePendingMsg( this.currentJournalIndex, GET_STATE_ENTRY_MESSAGE_TYPE, @@ -196,10 +196,15 @@ export class DurableExecutionStateMachine implements RestateContext { const result = await promise; - if (result == null || JSON.stringify(result) === "{}") { - return null; + if (result instanceof Buffer) { + const resultString = result.toString(); + if(resultString === "0"){ + return resultString as T; + } + + return JSON.parse(resultString) as T; } else { - return JSON.parse(result.toString()) as T; + return null; } } diff --git a/test/get_state.test.ts b/test/get_state.test.ts index 95a8e67e..6173249f 100644 --- a/test/get_state.test.ts +++ b/test/get_state.test.ts @@ -1,3 +1,5 @@ +"use strict"; + import { describe, expect } from "@jest/globals"; import * as restate from "../src/public_api"; import { TestDriver } from "./testdriver"; @@ -18,6 +20,7 @@ import { TestResponse, } from "../src/generated/proto/test"; import { ProtocolMode } from "../src/generated/proto/discovery"; +import { rlog } from "../src/utils/logger"; class GetStateGreeter implements TestGreeter { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -25,12 +28,44 @@ class GetStateGreeter implements TestGreeter { const ctx = restate.useContext(this); // state - const state = (await ctx.get("STATE")) || "nobody"; + let state = await ctx.get("STATE"); + if(state === null){ + state = "nobody" + } return TestResponse.create({ greeting: `Hello ${state}` }); } } +class NumberGetStateGreeter implements TestGreeter { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async greet(request: TestRequest): Promise { + const ctx = restate.useContext(this); + + // state + const state = (await ctx.get("STATE")) || 0; + const mynum: number = state as any as number; + rlog.debug(mynum + 1) + + return TestResponse.create({ greeting: `Hello ${state}` }); + } +} + +class NumberListGetStateGreeter implements TestGreeter { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async greet(request: TestRequest): Promise { + const ctx = restate.useContext(this); + + // state + const state = await ctx.get("STATE"); + if(state){ + return TestResponse.create({ greeting: `Hello index 0: ${state[0]} - index 1: ${state[1]}` }); + } else { + return TestResponse.create({ greeting: `Hello no state found` }); + } + } +} + describe("GetStateGreeter: With GetStateEntry already complete", () => { it("should call greet", async () => { const result = await new TestDriver( @@ -127,3 +162,110 @@ describe("GetStateGreeter: Without GetStateEntry and completed with later Comple ]); }); }); + +describe("GetStateGreeter: Without GetStateEntry and completed with later CompletionFrame with empty string", () => { + it("should call greet", async () => { + const result = await new TestDriver( + protoMetadata, + "TestGreeter", + new GetStateGreeter(), + "/test.TestGreeter/Greet", + [ + startMessage(1), + inputMessage(greetRequest("Till")), + completionMessage(1, Buffer.from(JSON.stringify(""))), + ] + ).run(); + + expect(result).toStrictEqual([ + getStateMessage("STATE"), + outputMessage(greetResponse("Hello ")), + ]); + }); +}); + +describe("NumberGetStateGreeter: Without GetStateEntry and completed with later CompletionFrame with numeric value 70", () => { + it("should call greet", async () => { + const result = await new TestDriver( + protoMetadata, + "TestGreeter", + new NumberGetStateGreeter(), + "/test.TestGreeter/Greet", + [ + startMessage(1), + inputMessage(greetRequest("Till")), + completionMessage(1, Buffer.from(JSON.stringify(70))), + ] + ).run(); + + expect(result).toStrictEqual([ + getStateMessage("STATE"), + outputMessage(greetResponse("Hello 70")), + ]); + }); +}); + +describe("NumberGetStateGreeter: Without GetStateEntry and completed with later CompletionFrame with value 0", () => { + it("should call greet", async () => { + const result = await new TestDriver( + protoMetadata, + "TestGreeter", + new NumberGetStateGreeter(), + "/test.TestGreeter/Greet", + [ + startMessage(1), + inputMessage(greetRequest("Till")), + completionMessage(1, Buffer.from(JSON.stringify(0))), + ] + ).run(); + + expect(result).toStrictEqual([ + getStateMessage("STATE"), + outputMessage(greetResponse("Hello 0")), + ]); + }); +}); + +describe("NumberListGetStateGreeter: Without GetStateEntry and completed with later CompletionFrame with list state", () => { + it("should call greet", async () => { + const result = await new TestDriver( + protoMetadata, + "TestGreeter", + new NumberListGetStateGreeter(), + "/test.TestGreeter/Greet", + [ + startMessage(1), + inputMessage(greetRequest("Till")), + completionMessage(1, Buffer.from(JSON.stringify([5, 4]))), + ] + ).run(); + + expect(result).toStrictEqual([ + getStateMessage("STATE"), + outputMessage(greetResponse("Hello index 0: 5 - index 1: 4")), + ]); + }); +}); + +describe("NumberListGetStateGreeter: Without GetStateEntry and completed with later CompletionFrame with empty list state", () => { + it("should call greet", async () => { + const result = await new TestDriver( + protoMetadata, + "TestGreeter", + new NumberListGetStateGreeter(), + "/test.TestGreeter/Greet", + [ + startMessage(1), + inputMessage(greetRequest("Till")), + completionMessage(1, Buffer.from(JSON.stringify([]))), + ] + ).run(); + + // For an empty list it will print undefined values for the first two indices + // but still recognize it as a list + expect(result).toStrictEqual([ + getStateMessage("STATE"), + outputMessage(greetResponse("Hello index 0: undefined - index 1: undefined")), + ]); + }); +}); \ No newline at end of file From c4f63c86e2b80bc3d3421e79cd2c39afbec50918 Mon Sep 17 00:00:00 2001 From: Giselle van Dongen Date: Wed, 24 May 2023 12:36:36 +0200 Subject: [PATCH 2/3] Format and remove log line --- src/state_machine.ts | 4 ++-- test/get_state.test.ts | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/state_machine.ts b/src/state_machine.ts index 951c0d26..8459f762 100644 --- a/src/state_machine.ts +++ b/src/state_machine.ts @@ -198,11 +198,11 @@ export class DurableExecutionStateMachine implements RestateContext { if (result instanceof Buffer) { const resultString = result.toString(); - if(resultString === "0"){ + if (resultString === "0") { return resultString as T; } - return JSON.parse(resultString) as T; + return JSON.parse(resultString) as T; } else { return null; } diff --git a/test/get_state.test.ts b/test/get_state.test.ts index 6173249f..5c679368 100644 --- a/test/get_state.test.ts +++ b/test/get_state.test.ts @@ -29,8 +29,8 @@ class GetStateGreeter implements TestGreeter { // state let state = await ctx.get("STATE"); - if(state === null){ - state = "nobody" + if (state === null) { + state = "nobody"; } return TestResponse.create({ greeting: `Hello ${state}` }); @@ -44,8 +44,6 @@ class NumberGetStateGreeter implements TestGreeter { // state const state = (await ctx.get("STATE")) || 0; - const mynum: number = state as any as number; - rlog.debug(mynum + 1) return TestResponse.create({ greeting: `Hello ${state}` }); } @@ -58,8 +56,10 @@ class NumberListGetStateGreeter implements TestGreeter { // state const state = await ctx.get("STATE"); - if(state){ - return TestResponse.create({ greeting: `Hello index 0: ${state[0]} - index 1: ${state[1]}` }); + if (state) { + return TestResponse.create({ + greeting: `Hello index 0: ${state[0]} - index 1: ${state[1]}`, + }); } else { return TestResponse.create({ greeting: `Hello no state found` }); } @@ -265,7 +265,9 @@ describe("NumberListGetStateGreeter: Without GetStateEntry and completed with la // but still recognize it as a list expect(result).toStrictEqual([ getStateMessage("STATE"), - outputMessage(greetResponse("Hello index 0: undefined - index 1: undefined")), + outputMessage( + greetResponse("Hello index 0: undefined - index 1: undefined") + ), ]); }); -}); \ No newline at end of file +}); From 800f651a801b03d946072629a399e5796f3d8138 Mon Sep 17 00:00:00 2001 From: Giselle van Dongen Date: Wed, 24 May 2023 13:14:37 +0200 Subject: [PATCH 3/3] Format --- test/get_state.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/get_state.test.ts b/test/get_state.test.ts index 5c679368..9d63adbc 100644 --- a/test/get_state.test.ts +++ b/test/get_state.test.ts @@ -20,7 +20,6 @@ import { TestResponse, } from "../src/generated/proto/test"; import { ProtocolMode } from "../src/generated/proto/discovery"; -import { rlog } from "../src/utils/logger"; class GetStateGreeter implements TestGreeter { // eslint-disable-next-line @typescript-eslint/no-unused-vars