Skip to content

Commit

Permalink
examples cleanup (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhirafovod authored May 21, 2024
1 parent 673aecf commit 9a2b6e6
Show file tree
Hide file tree
Showing 11 changed files with 1,454 additions and 764 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,11 @@ dist

# Internal state storage
.state

# temporary folkders
dumpster
example/experimental

# test arftifacts
SnapshotAndRecoverForWorkflowTest.json
defaultSnapshot.json
4 changes: 4 additions & 0 deletions example/homeworld.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
lukePersonDetails: ${ $fetch('https://swapi.dev/api/people/?name=luke').json().results[0] }
lukeHomeworldURL: ${ lukePersonDetails.homeworld }
homeworldDetails: ${ $fetch(lukeHomeworldURL).json() }
homeworldName: ${ homeworldDetails.name }
41 changes: 41 additions & 0 deletions example/obsolete/joinResistanceRecoverySerial.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"start": "${ (produceParams.data; $millis()) }",
"produceParams": {
"type": "rebelDispatch",
"client": {
"type": "test",
"data": [
"luke",
"han",
"leia"
]
}
},
"subscribeParams": {
"source": "cloudEvent",
"type": "/${ produceParams.type }",
"to": "/${saveRebelWorkflow}",
"subscriberId": "rebelArmy",
"initialPosition": "latest",
"parallelism": 1,
"client": {
"type": "test",
"acks": []
}
},
"saveRebelWorkflow": {
"function": "/${ \n function($rebel){ \n $rebel ~> $serial(\n [fetchRebel, saveRebel],\n {'workflowInvocation': $rebel} \n ) } }\n"
},
"fetchRebel": {
"function": "/${ \n function($rebel){(\n $console.debug('fetchRebel input: ' & $rebel);\n $r := $rebel.$fetch('https://swapi.tech/api/people/?name='&$).json().result[0].properties;\n $console.debug('fetchRebel fetched: ' & $r); \n $set('/fetchLog/-',$rebel);\n $console.debug('logged fetch: ' & $r);\n $r;\n )} \n}\n"
},
"saveRebel": {
"function": "/${ \n function($rebel){(\n $console.debug('saveRebel input: ' & $rebel);\n ($count(rebels) = 1 and simulateFailure)?(\n $set('/simulateFailure', false); \n $console.log('sleep forever on : ' & $rebel);\n $sleep(1000000);\n );\n $rebel ? $set('/rebels/-',{'name':$rebel.name, 'url':$rebel.homeworld});\n $console.debug('saveRebel saved: ' & {'name':$rebel.name, 'url':$rebel.homeworld});\n )} \n}\n"
},
"send$": "$publish(produceParams)",
"recv$": "$subscribe(subscribeParams)",
"rebels": [],
"fetchLog": [],
"simulateFailure": true,
"runtime": "${ (rebelForces; \"Rebel forces assembled in \" & $string($millis()-start) & \" ms\")}"
}
66 changes: 66 additions & 0 deletions example/obsolete/joinResistanceRecoverySerial.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
start: ${ (produceParams.data; $millis()) } #record start time, after test dataset has been computed
# producer will be sending some test data
produceParams:
type: "rebelDispatch"
client:
type: test # test client produces directly to the test subscriber dispatcher
data: ['luke', 'han', 'leia']
# the subscriber's 'to' function will be called on each received event
subscribeParams: #parameters for subscribing to an event
source: cloudEvent
type: /${ produceParams.type } # subscribe to the same topic as we are publishing to test events
to: /${saveRebelWorkflow}
subscriberId: rebelArmy
initialPosition: latest
parallelism: 1
client:
type: test
acks: []
saveRebelWorkflow:
function: |
/${
function($rebel){
$rebel ~> $serial(
[fetchRebel, saveRebel],
{'workflowInvocation': $rebel}
) } }
fetchRebel:
function: |
/${
function($rebel){(
$console.debug('fetchRebel input: ' & $rebel);
$r := $rebel.$fetch('https://swapi.tech/api/people/?name='&$).json().result[0].properties;
$console.debug('fetchRebel fetched: ' & $r);
$set('/fetchLog/-',$rebel);
$console.debug('logged fetch: ' & $r);
$r;
)}
}
saveRebel:
function: |
/${
function($rebel){(
$console.debug('saveRebel input: ' & $rebel);
($count(rebels) = 1 and simulateFailure)?(
$set('/simulateFailure', false);
$console.log('sleep forever on : ' & $rebel);
$sleep(1000000);
);
$rebel ? $set('/rebels/-',{'name':$rebel.name, 'url':$rebel.homeworld});
$console.debug('saveRebel saved: ' & {'name':$rebel.name, 'url':$rebel.homeworld});
)}
}
# starts producer function
send$: $publish(produceParams)
# starts consumer function
recv$: $subscribe(subscribeParams)
### below are workflow outputs and results
# the workflow will save the rebel to the rebels array below
rebels: [ ]
# fetch log
fetchLog: [ ]
# the below field is used to simulate a failure in the saveRebel function
# it will be set to false after the first failure
simulateFailure: true
# measure runtime
runtime: ${ (rebelForces; "Rebel forces assembled in " & $string($millis()-start) & " ms")}
File renamed without changes.
File renamed without changes.
File renamed without changes.
257 changes: 257 additions & 0 deletions src/test/Snapshot.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
// snapshotManager.test.ts
import { SnapshotManager } from '../workflow/SnapshotManager.js';
import fetchMock from 'jest-fetch-mock';

fetchMock.enableMocks();

describe('Snapshot.loadFromKnowledge', () => {
const sampleSnapshotResponse = {
"total": 2,
"items": [
{
"layerType": "TENANT",
"id": "IOrRxuuAqh",
"layerId": "2d4866c4-0a45-41ec-a534-011e5f4d970a",
"data": {
"id": "homeWorldSnapshotExample",
"type": "snapshot",
"snapshot": {
"output": {
"action": "{function:}",
"triggers": [],
"subscribeParams": {
"to": "{function:}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
},
"options": {
"snapshot": {
"seconds": 1
},
"importPath": "./stated-workflow"
},
"template": {
"action": "${ function($trigger){( $console.log($trigger); $set('/triggers/-', $trigger); $trigger)}}",
"triggers": [],
"subscribe$": "$subscribe(subscribeParams)",
"subscribeParams": {
"to": "/${action}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
}
}
},
"objectMimeType": "application/json",
"targetObjectId": null,
"patch": null,
"objectVersion": 1,
"blobInfo": null,
"createdAt": "2024-05-06T21:26:45.836Z",
"updatedAt": "2024-05-06T21:26:45.836Z",
"objectType": "sesergeeworkflow:snapshot",
"fqid": "sesergeeworkflow:snapshot/IOrRxuuAqh;layerId=2d4866c4-0a45-41ec-a534-011e5f4d970a;layerType=TENANT"
},
{
"layerType": "TENANT",
"id": "zq5bo7eVmi",
"layerId": "2d4866c4-0a45-41ec-a534-011e5f4d970a",
"data": {
"id": "homeWorldSnapshotExample",
"type": "snapshot",
"snapshot": {
"output": {
"action": "{function:}",
"triggers": [],
"subscribe$": "'listening clientType=test'",
"subscribeParams": {
"to": "{function:}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
},
"options": {
"snapshot": {
"seconds": 1
},
"importPath": "./stated-workflow"
},
"template": {
"action": "${ function($trigger){( $console.log($trigger); $set('/triggers/-', $trigger); $trigger)}}",
"triggers": [],
"subscribe$": "$subscribe(subscribeParams)",
"subscribeParams": {
"to": "/${action}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
}
}
},
"objectMimeType": "application/json",
"targetObjectId": null,
"patch": null,
"objectVersion": 1,
"blobInfo": null,
"createdAt": "2024-05-06T22:50:54.143Z",
"updatedAt": "2024-05-06T22:50:54.143Z",
"objectType": "sesergeeworkflow:snapshot",
"fqid": "sesergeeworkflow:snapshot/zq5bo7eVmi;layerId=2d4866c4-0a45-41ec-a534-011e5f4d970a;layerType=TENANT"
}
]
};

const expectedSnapshotsResult = [
{
"id": "homeWorldSnapshotExample",
"type": "snapshot",
"snapshot": {
"output": {
"action": "{function:}",
"triggers": [],
"subscribeParams": {
"to": "{function:}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
},
"options": {
"snapshot": {
"seconds": 1
},
"importPath": "./stated-workflow"
},
"template": {
"action": "${ function($trigger){( $console.log($trigger); $set('/triggers/-', $trigger); $trigger)}}",
"triggers": [],
"subscribe$": "$subscribe(subscribeParams)",
"subscribeParams": {
"to": "/${action}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
}
}
},
{
"id": "homeWorldSnapshotExample",
"type": "snapshot",
"snapshot": {
"output": {
"action": "{function:}",
"triggers": [],
"subscribe$": "'listening clientType=test'",
"subscribeParams": {
"to": "{function:}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
},
"options": {
"snapshot": {
"seconds": 1
},
"importPath": "./stated-workflow"
},
"template": {
"action": "${ function($trigger){( $console.log($trigger); $set('/triggers/-', $trigger); $trigger)}}",
"triggers": [],
"subscribe$": "$subscribe(subscribeParams)",
"subscribeParams": {
"to": "/${action}",
"type": "alertingTrigger",
"client": {
"type": "test"
},
"source": "cloudEvent",
"subscriberId": "alertingActionWorkflow"
}
}
}
}
]

beforeEach(() => {
// Reset environment variables and mocks
fetchMock.resetMocks();
delete process.env.APPD_JSON_STORE_URL;
});

it('should load snapshots from local development environment', async () => {
// Mock the local development server response
fetchMock.mockResponseOnce(JSON.stringify(sampleSnapshotResponse));
const snapshots = await SnapshotManager.loadFromKnowledge();

expect(fetchMock).toHaveBeenCalledWith(
'http://localhost:8081/knowledge-store/v2beta/objects/sesergeeworkflow:snapshot',
expect.objectContaining({
method: 'GET',
headers: expect.objectContaining({
'Accept': 'application/json',
'Layer-Id': '2d4866c4-0a45-41ec-a534-011e5f4d970a',
'Layer-Type': 'TENANT',
'appd-pty': 'IlVTRVIi',
'appd-pid': 'ImZvb0BiYXIuY29tIg=='
})
})
);

// Check if the returned data matches the mocked response
expect(snapshots).toEqual(expectedSnapshotsResult);
});

it('should load snapshots from Zodiac function environment', async () => {
// Set the environment variable to simulate the Zodiac function environment
process.env.APPD_JSON_STORE_URL = 'http://knowledge.local';

// Mock the Zodiac server response
fetchMock.mockResponseOnce(JSON.stringify(sampleSnapshotResponse));
const snapshots = await SnapshotManager.loadFromKnowledge();

expect(fetchMock).toHaveBeenCalledWith(
'http://knowledge.local/v2beta/objects/sesergeeworkflow:snapshot',
expect.objectContaining({
method: 'GET',
headers: expect.objectContaining({
'Accept': 'application/json',
'Layer-Id': '2d4866c4-0a45-41ec-a534-011e5f4d970a',
'Layer-Type': 'TENANT',
'appd-pty': 'IlVTRVIi',
'appd-pid': 'ImZvb0BiYXIuY29tIg=='
})
})
);

// Check if the returned data matches the mocked response
expect(snapshots).toEqual(expectedSnapshotsResult);
});
});
Loading

0 comments on commit 9a2b6e6

Please sign in to comment.