1+ using System ;
2+ using System . IO ;
3+ using System . Net ;
4+ using System . Text ;
5+ using System . Text . Json ;
6+ using System . Threading ;
7+ using System . Threading . Tasks ;
8+ using NUnit . Framework ;
9+ using QuestDB ;
10+
11+ namespace tcp_client_test ;
12+
13+ [ TestFixture ]
14+ public class JsonSpecTestRunner
15+ {
16+ private const int Port = 29472 ;
17+ private static readonly TestCase [ ] ? TestCases = ReadTestCases ( ) ;
18+
19+ [ TestCaseSource ( nameof ( TestCases ) ) ]
20+ public async Task Run ( TestCase testCase )
21+ {
22+ using var srv = CreateTcpListener ( Port ) ;
23+ srv . AcceptAsync ( ) ;
24+
25+ using var ls = await LineTcpSender . ConnectAsync ( IPAddress . Loopback . ToString ( ) , Port , tlsMode : TlsMode . Disable ) ;
26+ Exception ? exception = null ;
27+
28+ try
29+ {
30+ ls . Table ( testCase . table ) ;
31+ foreach ( var symbol in testCase . symbols )
32+ {
33+ ls . Symbol ( symbol . name , symbol . value ) ;
34+ }
35+
36+ foreach ( var column in testCase . columns )
37+ {
38+ switch ( column . type )
39+ {
40+ case "STRING" :
41+ ls . Column ( column . name , ( ( JsonElement ) column . value ) . GetString ( ) ) ;
42+ break ;
43+
44+ case "DOUBLE" :
45+ ls . Column ( column . name , ( ( JsonElement ) column . value ) . GetDouble ( ) ) ;
46+ break ;
47+
48+ case "BOOLEAN" :
49+ ls . Column ( column . name , ( ( JsonElement ) column . value ) . GetBoolean ( ) ) ;
50+ break ;
51+
52+ case "LONG" :
53+ ls . Column ( column . name , ( long ) ( ( JsonElement ) column . value ) . GetDouble ( ) ) ;
54+ break ;
55+
56+ default :
57+ throw new NotSupportedException ( "Column type not supported: " + column . type ) ;
58+ }
59+ }
60+
61+ ls . AtNow ( ) ;
62+ ls . Send ( ) ;
63+ }
64+ catch ( Exception ? ex )
65+ {
66+ if ( testCase . result . status == "SUCCESS" )
67+ {
68+ throw ;
69+ }
70+ exception = ex ;
71+ }
72+ ls . Dispose ( ) ;
73+
74+ if ( testCase . result . status == "SUCCESS" )
75+ {
76+ WaitAssert ( srv , testCase . result . line + "\n " ) ;
77+ }
78+ else if ( testCase . result . status == "ERROR" )
79+ {
80+ Assert . NotNull ( exception , "Exception should be thrown" ) ;
81+ if ( exception is NotSupportedException )
82+ {
83+ throw exception ;
84+ }
85+ }
86+ else
87+ {
88+ Assert . Fail ( "Unsupported test case result status: " + testCase . result . status ) ;
89+ }
90+ }
91+
92+ private static void WaitAssert ( DummyIlpServer srv , string expected )
93+ {
94+ var expectedLen = Encoding . UTF8 . GetBytes ( expected ) . Length ;
95+ for ( var i = 0 ; i < 500 && srv . TotalReceived < expectedLen ; i ++ ) Thread . Sleep ( 10 ) ;
96+ Assert . AreEqual ( expected , srv . GetTextReceived ( ) ) ;
97+ }
98+
99+ private DummyIlpServer CreateTcpListener ( int port , bool tls = false )
100+ {
101+ return new DummyIlpServer ( port , tls ) ;
102+ }
103+
104+ private static TestCase [ ] ? ReadTestCases ( )
105+ {
106+ using var jsonFile = File . OpenRead ( "ilp-client-interop-test.json" ) ;
107+ return JsonSerializer . Deserialize < TestCase [ ] > ( jsonFile ) ;
108+ }
109+
110+ public class TestCase
111+ {
112+ public string testName { get ; set ; }
113+ public string table { get ; set ; }
114+ public TestCaseSymbol [ ] symbols { get ; set ; }
115+ public TestCaseColumn [ ] columns { get ; set ; }
116+ public TestCaseResult result { get ; set ; }
117+
118+ public override string ToString ( )
119+ {
120+ return testName ;
121+ }
122+ }
123+
124+ public class TestCaseSymbol
125+ {
126+ public string name { get ; set ; }
127+ public string value { get ; set ; }
128+ }
129+
130+ public class TestCaseColumn
131+ {
132+ public string type { get ; set ; }
133+ public string name { get ; set ; }
134+ public object value { get ; set ; }
135+ }
136+
137+ public class TestCaseResult
138+ {
139+ public string status { get ; set ; }
140+ public string line { get ; set ; }
141+ }
142+ }
0 commit comments