Private
Public Access
Release 0.12.0
This commit is contained in:
1 parent
f74a658097
commit
7f6eeab39e
48 files changed
+3617
-1266
No files matched your search
+105
-30
@@ -5,35 +5,110 @@
|
||||
#include "target.h"
|
||||
#include "layout.h"
|
||||
#include "receiver_stream.h"
|
||||
static void fixture(PlaybackJson *json,bool modern,bool login){
|
||||
int server=socket(AF_INET,SOCK_STREAM,0);assert(server>=0);
|
||||
struct sockaddr_in address={.sin_family=AF_INET,.sin_addr={htonl(INADDR_LOOPBACK)}};
|
||||
assert(!bind(server,(void*)&address,sizeof(address)) && !listen(server,1));socklen_t size=sizeof(address);assert(!getsockname(server,(void*)&address,&size));
|
||||
target.port=ntohs(address.sin_port);snprintf(target.token,sizeof(target.token),"%s",login?"fixture-token":"");
|
||||
pid_t child=fork();assert(child>=0);
|
||||
if(!child){
|
||||
int fd=accept(server,NULL,NULL);if(fd<0)_exit(1);FILE *input=fdopen(dup(fd),"r");char request[512];
|
||||
if(login){if(!fgets(request,sizeof(request),input) || !strstr(request,"authorize"))_exit(2);write(fd,"{\"success\":true}\n",17);}
|
||||
if(!fgets(request,sizeof(request),input) || !strstr(request,"serverinfo"))_exit(3);
|
||||
const char *layout="{\"success\":true,\"info\":{\"leds\":[{\"hmin\":0,\"hmax\":1,\"vmin\":0,\"vmax\":0.1}]}}\n";write(fd,layout,strlen(layout));
|
||||
if(!fgets(request,sizeof(request),input) || !strstr(request,"ledstream-start"))_exit(4);
|
||||
const char *reply=modern?"{\"success\":true,\"command\":\"ledcolors-ledstream-update\",\"data\":{\"leds\":[20,30,40]}}\n":"{\"success\":true,\"command\":\"ledcolors-ledstream-update\",\"result\":{\"leds\":[20,30,40]}}\n";
|
||||
write(fd,reply,13);usleep(20000);write(fd,reply+13,strlen(reply)-13);usleep(500000);close(fd);fclose(input);close(server);_exit(0);
|
||||
}
|
||||
stream_close(0);stream.retry_at=0;
|
||||
for(unsigned i=0;i<500 && !stream.valid;i++){stream_tick(json,1000+i*5,true);usleep(1000);}
|
||||
assert(stream.valid && stream.sequence==1 && stream.count==1);
|
||||
for(unsigned r=0;r<16;r++){assert(stream.colors[r][0]==20 && stream.colors[r][1]==30 && stream.colors[r][2]==40);}
|
||||
void *bad=json->parse("{\"result\":{\"leds\":[0,0,999]}}");assert(!stream_colors(json,bad,2000));json->put(bad);assert(stream.colors[0][2]==40);
|
||||
bad=json->parse("{\"data\":{\"leds\":[0,0,0]}}");assert(stream_colors(json,bad,2000));json->put(bad);assert(stream.colors[0][2]==0);
|
||||
bad=json->parse("{\"data\":{\"leds\":[1,2,3,4,5,6]}}");assert(!stream_colors(json,bad,2000) && !stream.revision);json->put(bad);
|
||||
stream_tick(json,2001,false);assert(stream.fd<0 && !stream.valid);int status;waitpid(child,&status,0);assert(WIFEXITED(status) && !WEXITSTATUS(status));close(server);
|
||||
static void fixture(PlaybackJson *json, bool modern, bool login) {
|
||||
int server = socket(AF_INET, SOCK_STREAM, 0);
|
||||
assert(server >= 0);
|
||||
struct sockaddr_in address = {.sin_family = AF_INET, .sin_addr = {htonl(INADDR_LOOPBACK)}};
|
||||
assert(!bind(server, (void *)&address, sizeof(address)) && !listen(server, 1));
|
||||
socklen_t size = sizeof(address);
|
||||
assert(!getsockname(server, (void *)&address, &size));
|
||||
target.port = ntohs(address.sin_port);
|
||||
snprintf(target.token, sizeof(target.token), "%s", login ? "fixture-token" : "");
|
||||
pid_t child = fork();
|
||||
assert(child >= 0);
|
||||
if (!child) {
|
||||
int fd = accept(server, NULL, NULL);
|
||||
if (fd < 0)
|
||||
_exit(1);
|
||||
FILE *input = fdopen(dup(fd), "r");
|
||||
char request[512];
|
||||
if (login) {
|
||||
if (!fgets(request, sizeof(request), input) || !strstr(request, "authorize"))
|
||||
_exit(2);
|
||||
write(fd, "{\"success\":true}\n", 17);
|
||||
}
|
||||
if (!fgets(request, sizeof(request), input) || !strstr(request, "serverinfo"))
|
||||
_exit(3);
|
||||
const char *layout = "{\"success\":true,\"info\":{\"leds\":[{\"hmin\":0,\"hmax\":1,"
|
||||
"\"vmin\":0,\"vmax\":0.1}]}}\n";
|
||||
write(fd, layout, strlen(layout));
|
||||
if (!fgets(request, sizeof(request), input) || !strstr(request, "ledstream-start"))
|
||||
_exit(4);
|
||||
const char *reply = modern ? "{\"success\":true,\"command\":\"ledcolors-ledstream-update\","
|
||||
"\"data\":{\"leds\":[20,30,40]}}\n"
|
||||
: "{\"success\":true,\"command\":\"ledcolors-ledstream-update\","
|
||||
"\"result\":{\"leds\":[20,30,40]}}\n";
|
||||
write(fd, reply, 13);
|
||||
usleep(20000);
|
||||
write(fd, reply + 13, strlen(reply) - 13);
|
||||
usleep(500000);
|
||||
close(fd);
|
||||
fclose(input);
|
||||
close(server);
|
||||
_exit(0);
|
||||
}
|
||||
stream_close(0);
|
||||
stream.retry_at = 0;
|
||||
for (unsigned i = 0; i < 500 && !stream.valid; i++) {
|
||||
stream_tick(json, 1000 + i * 5, true);
|
||||
usleep(1000);
|
||||
}
|
||||
assert(stream.valid && stream.sequence == 1 && stream.count == 1);
|
||||
for (unsigned r = 0; r < 16; r++) {
|
||||
assert(stream.colors[r][0] == 20 && stream.colors[r][1] == 30 && stream.colors[r][2] == 40);
|
||||
}
|
||||
/* More than the eight-message budget, with no further socket writes. */
|
||||
const char *buffered =
|
||||
"{\"command\":\"ledcolors-ledstream-update\",\"data\":{\"leds\":[50,60,70]}}\n";
|
||||
stream.used = 0;
|
||||
for (unsigned i = 0; i < 17; i++) {
|
||||
memcpy(stream.data + stream.used, buffered, strlen(buffered));
|
||||
stream.used += strlen(buffered);
|
||||
}
|
||||
stream.data[stream.used] = 0;
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
stream_tick(json, 1900 + i, true);
|
||||
assert(stream.sequence == 18 && stream.used == 0 && stream.colors[0][0] == 50);
|
||||
void *bad = json->parse("{\"result\":{\"leds\":[0,0,999]}}");
|
||||
assert(!stream_colors(json, bad, 2000));
|
||||
json->put(bad);
|
||||
assert(stream.colors[0][2] == 70);
|
||||
bad = json->parse("{\"data\":{\"leds\":[0,0,0]}}");
|
||||
assert(stream_colors(json, bad, 2000));
|
||||
json->put(bad);
|
||||
assert(stream.colors[0][2] == 0);
|
||||
bad = json->parse("{\"data\":{\"leds\":[1,2,3,4,5,6]}}");
|
||||
assert(!stream_colors(json, bad, 2000) && !stream.revision);
|
||||
json->put(bad);
|
||||
stream_tick(json, 2001, false);
|
||||
assert(stream.fd < 0 && !stream.valid);
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
assert(WIFEXITED(status) && !WEXITSTATUS(status));
|
||||
close(server);
|
||||
}
|
||||
int main(void){
|
||||
PlaybackJson json={0};assert(playback_json_init(&json));fixture(&json,false,false);fixture(&json,true,true);
|
||||
stream_start(1000);stream_tick(&json,5000,true);assert(stream.fd<0);stream_close(0);
|
||||
TargetConfig copy=target;assert(target_valid(©));assert(target_piccap_compatible(©));assert(!target_piccap_local(©));assert(target_piccap_host(©));
|
||||
assert(!target_parse(&json,"{}",©));assert(!target_save("/no/such/profile",©));assert(!target_load(&json,"/no/such/profile",©));
|
||||
int fd=target_connect(©);if(fd>=0)close(fd);
|
||||
dlclose(json.lib);puts("PASS: fragmented raw LED subscription, token login, old/new envelopes, invalid samples, real black, timeout and cleanup");return 0;
|
||||
int main(void) {
|
||||
PlaybackJson json = {0};
|
||||
assert(playback_json_init(&json));
|
||||
fixture(&json, false, false);
|
||||
fixture(&json, true, true);
|
||||
stream_start(1000);
|
||||
stream_tick(&json, 5000, true);
|
||||
assert(stream.fd < 0);
|
||||
stream_close(0);
|
||||
TargetConfig copy = target;
|
||||
assert(target_valid(©));
|
||||
assert(target_piccap_compatible(©));
|
||||
assert(!target_piccap_local(©));
|
||||
assert(target_piccap_host(©));
|
||||
assert(!target_parse(&json, "{}", ©));
|
||||
assert(!target_save("/no/such/profile", ©));
|
||||
assert(!target_load(&json, "/no/such/profile", ©));
|
||||
int fd = target_connect(©);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
dlclose(json.lib);
|
||||
puts("PASS: fragmented raw LED subscription, token login, old/new envelopes, invalid samples, "
|
||||
"real black, timeout and cleanup");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user