Skip to content

Commit 7336064

Browse files
authored
Add dummy proxy (#21)
* Add proxy forwarding with dummy * Fix: two-way forwarding in dummy
1 parent 710be56 commit 7336064

File tree

6 files changed

+82
-7
lines changed

6 files changed

+82
-7
lines changed

src/framework/Testee.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class Testee { // TODO unified with testbed interface
9797
if (proxy) {
9898
this.proxy = proxy;
9999
await this.proxy.sendRequest(new SourceMap.Mapping(), Message.proxifyRequest);
100-
args = args.concat(['--proxy', `${spec.options.port}`]);
100+
args = args.concat(['--proxy', `${spec.dummy.port}`]);
101101
}
102102
}
103103

src/manage/Uploader.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export class UploaderFactory {
3939
return new ArduinoUploader(this.arduino, args, specification.options as SerialOptions);
4040
case PlatformType.emulator:
4141
case PlatformType.emu2emu:
42+
case PlatformType.emuproxy:
4243
return new EmulatorUploader(this.emulator, args, specification.options as SubprocessOptions);
4344
case PlatformType.debug:
4445
return new EmulatorConnector(specification.options as SubprocessOptions)

src/messaging/MessageQueue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class MessageQueue implements Iterable<string> {
3232
return last !== undefined && !last.includes(this.delimiter);
3333
}
3434

35-
private hasCompleteMessage(): boolean {
35+
public hasCompleteMessage(): boolean {
3636
return this.queue.length > 0 && (!this.lastMessageIncomplete() || this.queue.length > 1);
3737
}
3838

src/testbeds/Emulator.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import {Platform} from './Platform';
22
import {SubProcess} from '../bridge/SubProcess';
3+
import {Connection} from '../bridge/Connection';
4+
import {UploaderFactory} from '../manage/Uploader';
5+
import {ARDUINO, EMULATOR} from '../util/env';
6+
import {ProxySpecification} from './TestbedSpecification';
7+
import {CompileOutput} from '../manage/Compiler';
8+
import * as net from 'node:net';
9+
import {SourceMap} from '../sourcemap/SourceMap';
10+
import {Request} from '../messaging/Message';
11+
import {AddressInfo, Socket} from 'node:net';
12+
import {MessageQueue} from '../messaging/MessageQueue';
313

414
export class Emulator extends Platform {
515
readonly name: string = 'Emulator';
@@ -18,3 +28,54 @@ export class Emulator extends Platform {
1828
return super.kill();
1929
}
2030
}
31+
32+
/**
33+
* Dummy proxy object, forwards all requests on a dummy port to the real proxy instance
34+
*
35+
* todo this allows for testing the communication between supervisor and proxy
36+
*/
37+
export class DummyProxy extends Emulator {
38+
dummy: net.Server;
39+
40+
protected forwarding: MessageQueue;
41+
42+
private supervisor?: Socket;
43+
44+
constructor(connection: SubProcess) {
45+
super(connection);
46+
47+
this.forwarding = new MessageQueue('\n');
48+
49+
this.dummy = new net.Server();
50+
}
51+
52+
public async init(specification: ProxySpecification) {
53+
this.dummy.on('connection', (connection) => {
54+
this.supervisor = connection;
55+
connection.on('data', (data) => {
56+
this.connection.channel.write(data.toString());
57+
})
58+
});
59+
this.dummy.listen(specification.dummy.port);
60+
}
61+
62+
protected listen(): void {
63+
this.connection.channel.on('data', (data: Buffer) => {
64+
if (this.waitingForMessages()) {
65+
this.messages.push(data.toString());
66+
this.process();
67+
} else {
68+
this.forwarding.push(data.toString());
69+
while (this.forwarding.hasCompleteMessage()) {
70+
const message = this.forwarding.pop()
71+
if(!message?.includes('Interrupt')) this.supervisor!.write(message!.toString());
72+
}
73+
74+
}
75+
});
76+
}
77+
78+
private waitingForMessages(): boolean {
79+
return this.requests.length > 0;
80+
}
81+
}

src/testbeds/TestbedFactory.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import {Testbed} from './Testbed';
22
import {ARDUINO, EMULATOR, WABT} from '../util/env';
33
import {CompileOutput, CompilerFactory} from '../manage/Compiler';
4-
import {Emulator} from './Emulator';
4+
import {DummyProxy, Emulator} from './Emulator';
55
import {UploaderFactory} from '../manage/Uploader';
66
import {Connection} from '../bridge/Connection';
77
import {Arduino} from './Arduino';
88
import {Serial} from '../bridge/Serial';
99
import {SubProcess} from '../bridge/SubProcess';
10-
import {TestbedSpecification, PlatformType} from './TestbedSpecification';
10+
import {PlatformType, ProxySpecification, TestbedSpecification} from './TestbedSpecification';
1111

1212
export class TestbedFactory {
1313
public readonly timeout: number;
@@ -31,6 +31,10 @@ export class TestbedFactory {
3131
case PlatformType.emu2emu:
3232
case PlatformType.debug:
3333
return new Emulator(connection as SubProcess);
34+
case PlatformType.emuproxy:
35+
const dummy = new DummyProxy(connection as SubProcess);
36+
await dummy.init(specification as ProxySpecification);
37+
return dummy;
3438
default:
3539
return Promise.reject('Platform not implemented.');
3640
}

src/testbeds/TestbedSpecification.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export enum PlatformType {
22
arduino,
33
emulator,
44
emu2emu,
5+
emuproxy,
56
debug
67
}
78

@@ -33,11 +34,11 @@ export class OutofPlaceSpecification implements TestbedSpecification {
3334
public readonly type: PlatformType = PlatformType.emu2emu;
3435
public readonly options: SupervisorOptions;
3536

36-
public readonly proxy: EmulatorSpecification;
37+
public readonly proxy: ProxySpecification;
3738

38-
constructor(supervisor: number, proxy: number) {
39+
constructor(supervisor: number, proxy: number, dummy: number = proxy + 1) {
3940
this.options = {port: supervisor, proxy: proxy};
40-
this.proxy = new EmulatorSpecification(proxy);
41+
this.proxy = new ProxySpecification(proxy, dummy);
4142
}
4243
}
4344

@@ -51,6 +52,14 @@ export class EmulatorSpecification implements TestbedSpecification {
5152
}
5253
}
5354

55+
export class ProxySpecification extends EmulatorSpecification {
56+
public readonly dummy: SubprocessOptions;
57+
constructor(port: number, dummy: number) {
58+
super(port, PlatformType.emuproxy);
59+
this.dummy = {port: dummy};
60+
}
61+
}
62+
5463
export class ArduinoSpecification implements TestbedSpecification {
5564
public readonly type: PlatformType;
5665
public readonly options: SerialOptions;

0 commit comments

Comments
 (0)