• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

leeonky / test-charm-java / 132

28 Feb 2025 01:29AM UTC coverage: 74.304% (+3.0%) from 71.301%
132

push

circleci

leeonky
Allow pass test

15 of 16 new or added lines in 2 files covered. (93.75%)

16 existing lines in 3 files now uncovered.

7874 of 10597 relevant lines covered (74.3%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.76
/DAL-extension-inspector/src/main/java/com/github/leeonky/dal/extensions/inspector/Inspector.java
1
package com.github.leeonky.dal.extensions.inspector;
2

3
import com.github.leeonky.dal.DAL;
4
import com.github.leeonky.dal.runtime.RuntimeContextBuilder;
5
import com.github.leeonky.interpreter.InterpreterException;
6
import com.github.leeonky.util.Suppressor;
7
import io.javalin.Javalin;
8
import io.javalin.http.staticfiles.Location;
9
import io.javalin.websocket.WsContext;
10

11
import java.net.InetAddress;
12
import java.net.NetworkInterface;
13
import java.util.*;
14
import java.util.concurrent.ConcurrentHashMap;
15
import java.util.concurrent.CountDownLatch;
16
import java.util.function.Supplier;
17
import java.util.stream.Collectors;
18

19
import static com.github.leeonky.util.function.Extension.getFirstPresent;
20
import static java.util.Objects.requireNonNull;
21
import static java.util.Optional.ofNullable;
22

23
public class Inspector {
24
    private static Inspector inspector = null;
1✔
25
    private static Mode mode = null;
1✔
26
    private final Javalin javalin;
27
    private final CountDownLatch serverReadyLatch = new CountDownLatch(1);
1✔
28
    private final Set<DAL> instances = new LinkedHashSet<>();
1✔
29
    //   TODO refactor
30
    private final Map<String, WsContext> clientConnections = new ConcurrentHashMap<>();
1✔
31
    private final Map<String, Set<String>> clientMonitors = new ConcurrentHashMap<>();
1✔
32
    private final Map<String, DalInstance> dalInstances = new ConcurrentHashMap<>();
1✔
33
    private static Supplier<Object> defaultInput = () -> null;
1✔
34

35
    public Inspector() {
1✔
36
        DalInstance defaultInstance = new DalInstance(() -> defaultInput.get(), DAL.create(InspectorExtension.class), "");
1✔
37
        defaultInstance.running = false;
1✔
38
        dalInstances.put("Try It!", defaultInstance);
1✔
39
        javalin = Javalin.create(config -> config.addStaticFiles("/public", Location.CLASSPATH))
1✔
40
                .events(event -> event.serverStarted(serverReadyLatch::countDown));
1✔
41
        requireNonNull(javalin.jettyServer()).setServerPort(getServerPort());
1✔
42
        javalin.get("/", ctx -> ctx.redirect("/index.html"));
1✔
43
        javalin.post("/api/execute", ctx -> ctx.html(execute(ctx.queryParam("name"), ctx.body())));
1✔
44
        javalin.post("/api/exchange", ctx -> exchange(ctx.queryParam("session"), ctx.body()));
1✔
45
        javalin.post("/api/pass", ctx -> pass(ctx.queryParam("name")));
1✔
46
        javalin.post("/api/release", ctx -> release(ctx.queryParam("name")));
1✔
47
        javalin.post("/api/release-all", ctx -> releaseAll());
1✔
48
        javalin.get("/api/request", ctx -> ctx.html(request(ctx.queryParam("name"))));
1✔
49
        javalin.ws("/ws/exchange", ws -> {
1✔
50
            ws.onConnect(ctx -> {
1✔
51
                clientConnections.put(ctx.getSessionId(), ctx);
1✔
52
                sendInstances(ctx);
1✔
53
            });
1✔
54
            ws.onClose(ctx -> clientConnections.remove(ctx.getSessionId()));
1✔
55
        });
1✔
56
        javalin.start();
1✔
57
    }
1✔
58

59
    private void pass(String name) {
60
        if (!name.equals("Try It!")) {
1✔
61
            DalInstance remove = dalInstances.remove(name);
1✔
62
            if (remove != null)
1✔
63
                remove.pass();
1✔
64
        }
65
    }
1✔
66

67
    private void waitForReady() {
68
        Suppressor.run(serverReadyLatch::await);
1✔
69
    }
1✔
70

71
    private static int getServerPort() {
72

73
        return getFirstPresent(() -> ofNullable(System.getenv("DAL_INSPECTOR_PORT")),
1✔
74
                () -> ofNullable(System.getProperty("dal.inspector.port")))
1✔
75
                .map(Integer::parseInt)
1✔
76
                .orElse(10082);
1✔
77
    }
78

79
    public static void ready() {
80
        inspector.waitForReady();
1✔
81
    }
1✔
82

83
    private void releaseAll() {
84
        for (String instanceName : new ArrayList<>(dalInstances.keySet()))
1✔
85
            release(instanceName);
1✔
86
    }
1✔
87

88
    private void release(String name) {
89
        if (!name.equals("Try It!")) {
1✔
90
            DalInstance remove = dalInstances.remove(name);
1✔
91
            if (remove != null)
1✔
92
                remove.release();
1✔
93
        }
94
    }
1✔
95

96
    public static void setDefaultMode(Mode mode) {
97
        Inspector.mode = mode;
1✔
98
    }
1✔
99

100
    private void exchange(String session, String body) {
101
        if (clientConnections.containsKey(session)) {
1✔
102
            clientMonitors.put(session, Arrays.stream(body.trim().split("\\n")).map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toSet()));
1✔
103

104
            for (DalInstance dalInstance : dalInstances.values()) {
1✔
105
                if (dalInstance.running)
1✔
106
                    clientConnections.get(session).send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
107
                        put("request", dalInstance.dal.getName());
1✔
108
                    }}));
1✔
109
            }
1✔
110
        }
111
    }
1✔
112

113
    public static class DalInstance {
114
        private final Supplier<Object> input;
115
        private boolean running = true;
1✔
116
        private boolean pass = false;
1✔
117
        private final DAL dal;
118
        private final String code;
119

120
        public DalInstance(Supplier<Object> input, DAL dal, String code) {
1✔
121
            this.input = input;
1✔
122
            this.dal = dal;
1✔
123
            this.code = code;
1✔
124
        }
1✔
125

126
        public String execute(String code) {
127
            Map<String, String> response = new HashMap<>();
1✔
128
            Object inputObject = input.get();
1✔
129
            RuntimeContextBuilder.DALRuntimeContext runtimeContext = dal.getRuntimeContextBuilder().build(inputObject);
1✔
130
            try {
131
                response.put("root", runtimeContext.wrap(inputObject).dumpAll());
1✔
132
                response.put("inspect", dal.compileSingle(code, runtimeContext).inspect());
1✔
133
                response.put("result", runtimeContext.wrap(dal.evaluate(inputObject, code)).dumpAll());
1✔
134
            } catch (InterpreterException e) {
1✔
135
                response.put("error", e.show(code) + "\n\n" + e.getMessage());
1✔
136
            }
1✔
137
            return ObjectWriter.serialize(response);
1✔
138
        }
139

140
        public boolean hold() {
141
            System.err.println("Waiting for DAL inspector release...");
1✔
142
            try {
143
                Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
1✔
144

145
                System.err.println("\tDal inspector running at:");
1✔
146

147
                while (interfaces.hasMoreElements()) {
1✔
148
                    Enumeration<InetAddress> inetAddresses = interfaces.nextElement().getInetAddresses();
1✔
149
                    while (inetAddresses.hasMoreElements()) {
1✔
150
                        InetAddress address = inetAddresses.nextElement();
1✔
151
                        System.err.printf("\t\thttp://%s:%d%n", address.getHostAddress(), getServerPort());
1✔
152
                    }
1✔
153
                }
1✔
UNCOV
154
            } catch (Exception ignore) {
×
155
            }
1✔
156
            //        TODO use sempahore to wait for the result
157
            while (running)
1✔
158
                Suppressor.run(() -> Thread.sleep(20));
1✔
159
//            TODO use logger
160
            System.err.println("DAL inspector released with pass: " + pass);
1✔
161
            return pass;
1✔
162
        }
163

164
        public void release() {
165
            running = false;
1✔
166
        }
1✔
167

168
        public void pass() {
169
            pass = true;
1✔
170
            release();
1✔
171
        }
1✔
172
    }
173

174
    public boolean inspectInner(DAL dal, Object input, String code) {
175
        if (isRecursive())
1✔
176
            return false;
1✔
177
//        lock inspect by name
178
//        check mode
179
        if (currentMode() == Mode.FORCED) {
1✔
180
            DalInstance dalInstance = new DalInstance(() -> input, dal, code);
1✔
181
            dalInstances.put(dal.getName(), dalInstance);
1✔
182

183
//            List<WsContext> monitored = clientMonitors.entrySet().stream().filter(e -> e.getValue().contains(dal.getName()))
184
//                    .map(o -> clientConnections.get(o.getKey()))
185
//                    .collect(Collectors.toList());
186
//            TODO check monitor flag
187
            for (WsContext wsContext : clientConnections.values()) {
1✔
188
                wsContext.send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
189
                    put("request", dal.getName());
1✔
190
                }}));
1✔
191
            }
1✔
192

193
            return dalInstance.hold();
1✔
194

195
        } else {
196
//        TODO refactor
197
            List<WsContext> monitored = clientMonitors.entrySet().stream().filter(e -> e.getValue().contains(dal.getName()))
1✔
198
                    .map(o -> clientConnections.get(o.getKey()))
1✔
199
                    .collect(Collectors.toList());
1✔
200
            if (!monitored.isEmpty()) {
1✔
201
                DalInstance dalInstance = new DalInstance(() -> input, dal, code);
1✔
202
                dalInstances.put(dal.getName(), dalInstance);
1✔
203
                for (WsContext wsContext : monitored) {
1✔
204
                    wsContext.send(ObjectWriter.serialize(new HashMap<String, String>() {{
1✔
205
                        put("request", dal.getName());
1✔
206
                    }}));
1✔
207
                }
1✔
NEW
208
                return dalInstance.hold();
×
209
            }
210
            return false;
1✔
211
        }
212
    }
213

214
    public static boolean inspect(DAL dal, Object input, String code) {
215
        if (currentMode() != Mode.DISABLED)
1✔
216
            return inspector.inspectInner(dal, input, code);
1✔
UNCOV
217
        return false;
×
218
    }
219

220
    private String request(String name) {
221
//       TODO reject other request
222
        return dalInstances.get(name).code;
1✔
223
    }
224

225
    private String execute(String name, String code) {
226
        return dalInstances.get(name).execute(code);
1✔
227
    }
228

229
    public static void register(DAL dal) {
230
        inspector.addInstance(dal);
1✔
231
    }
1✔
232

233
    private void addInstance(DAL dal) {
234
        instances.add(dal);
1✔
235
        for (WsContext ctx : clientConnections.values()) {
1✔
236
            sendInstances(ctx);
1✔
237
        }
1✔
238
    }
1✔
239

240
    private void sendInstances(WsContext ctx) {
241
        ctx.send(ObjectWriter.serialize(new HashMap<String, Object>() {{
1✔
242
            put("instances", instances.stream().map(DAL::getName).collect(Collectors.toSet()));
1✔
243
            put("session", ctx.getSessionId());
1✔
244
        }}));
1✔
245
    }
1✔
246

247
    private void stop() {
248
        javalin.close();
1✔
249
    }
1✔
250

251
    public static void launch() {
252
        if (inspector == null) {
1✔
253
            inspector = new Inspector();
1✔
254
        }
255
    }
1✔
256

257
    public static void shutdown() {
258
        if (inspector != null) {
1✔
259
            inspector.stop();
1✔
260
            inspector = null;
1✔
261
        }
262
    }
1✔
263

264
    public static void setDefaultInput(Supplier<Object> supplier) {
265
        defaultInput = supplier;
1✔
266
    }
1✔
267

268
    public static Mode currentMode() {
269
        return getFirstPresent(() -> ofNullable(mode),
1✔
UNCOV
270
                () -> ofNullable(System.getenv("DAL_INSPECTOR_MODE")).map(Mode::valueOf),
×
UNCOV
271
                () -> ofNullable(System.getProperty("dal.inspector.mode")).map(Mode::valueOf))
×
272
                .orElse(Mode.DISABLED);
1✔
273
    }
274

275
    public enum Mode {
1✔
276
        DISABLED, FORCED, AUTO
1✔
277
    }
278

279
    private boolean isRecursive() {
280
        for (StackTraceElement stack : Thread.currentThread().getStackTrace())
1✔
281
            if (DalInstance.class.getName().equals(stack.getClassName()))
1✔
282
                return true;
1✔
283
        return false;
1✔
284
    }
285

286
    public static void main(String[] args) {
UNCOV
287
        launch();
×
UNCOV
288
    }
×
289
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc