Skip to content

Commit

Permalink
Adapt Android RN test fixture to work with BitBar (#1957)
Browse files Browse the repository at this point in the history
* Add naive start of config file implementation

* Move implementation into kotlin for simplicity

* Slight refactor for testing

* Cut pipeline right down for testing

* Add missing imports and variables

* Work around missing references

* Add log import

* Fix syntax error

* Remove invalid log

* Add debug log

* Add more debugging

* Add more debugging

* Use proper async await to return maze-runner address

* Naive implementation of cocoa file reading

* More debugging

* Don't pass address back up to JS

* Remove superfluous function

* Remove invalid import

* Fix redeclaration error

* Add general bridging header import

* Add separate interface for config loader

* Attempt to use seperate bridging header location

* Remove config reading from iOS RN test fixtures due to build issues

* Add feedback and extra guards against missing endpoints

* Revert changes to buildkite pipeline
  • Loading branch information
Cawllec committed May 15, 2023
1 parent b688cd0 commit b538576
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 14 deletions.
16 changes: 10 additions & 6 deletions test/react-native/features/fixtures/app/scenario_js/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default class App extends Component {
currentScenario: '',
scenarioMetaData: '',
apiKey: '12312312312312312312312312312312',
notifyEndpoint: 'http://bs-local.com:9339/notify',
sessionsEndpoint: 'http://bs-local.com:9339/sessions'
notifyEndpoint: '',
sessionsEndpoint: ''
}
}

Expand All @@ -27,14 +27,18 @@ export default class App extends Component {
}

getConfiguration = () => {
return {
var config = {
apiKey: this.state.apiKey,
endpoints: {
autoTrackSessions: false
}

if (this.state.notifyEndpoint && this.state.sessionsEndpoint) {
config.endpoints = {
notify: this.state.notifyEndpoint,
sessions: this.state.sessionsEndpoint
},
autoTrackSessions: false
}
}
return config
}

setScenario = newScenario => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ BugsnagConfiguration *createConfiguration(NSDictionary * options);

@end


#endif /* BugsnagModule_h */
17 changes: 14 additions & 3 deletions test/react-native/features/fixtures/ios-module/BugsnagModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,21 @@ @implementation BugsnagModule
NSLog(@"key: %@, value: %@ \n", key, [options objectForKey:key]);
}
BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:options[@"apiKey"]];
NSDictionary *endpointsIn = options[@"endpoints"];
NSString *notifyEndpoint = endpointsIn[@"notify"];
NSString *sessionsEndpoint = endpointsIn[@"sessions"];
NSString *notifyEndpoint;
NSString *sessionsEndpoint;
if (options[@"endpoints"] != nil && options[@"endpoints"][@"notify"] != nil && options[@"endpoints"][@"sessions"] != nil) {
NSDictionary *endpointsIn = options[@"endpoints"];
notifyEndpoint = endpointsIn[@"notify"];
sessionsEndpoint = endpointsIn[@"sessions"];
} else {
NSString *baseAddress = @"bs-local.com:9339";
notifyEndpoint = [NSString stringWithFormat:@"http://%@/notify", baseAddress];
sessionsEndpoint = [NSString stringWithFormat:@"http://%@/sessions", baseAddress];
}
NSLog(@"Notify endpoint set to: %@\n", notifyEndpoint);
NSLog(@"Sessions endpoint set to: %@\n", sessionsEndpoint);
BugsnagEndpointConfiguration *endpoints = [[BugsnagEndpointConfiguration alloc] initWithNotify:notifyEndpoint sessions:sessionsEndpoint];

[config setEndpoints:endpoints];
[config setAutoTrackSessions:[[options objectForKey:@"autoTrackSessions"]boolValue]];
config.enabledErrorTypes.ooms = NO; // Set by default, will add an override as required
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// ConfigFileReader.swift
// reactnative
//
// Created by Alex Moinet on 04/05/2023.
// Copyright © 2023 Facebook. All rights reserved.
//

import Foundation

class FixtureConfig: Codable {
var maze_address: String
}

class ConfigFileReader:NSObject {
func loadMazeRunnerAddress() -> String {
let bsAddress = "http://bs-local.com:9339"

// Only iOS 12 and above will run on BitBar for now
if #available(iOS 12.0, *) {} else {
return bsAddress;
}

for _ in 1...60 {
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

NSLog("Reading Maze Runner address from fixture_config.json")
do {
let fileUrl = URL(fileURLWithPath: "fixture_config",
relativeTo: documentsUrl).appendingPathExtension("json")
let savedData = try Data(contentsOf: fileUrl)
if let contents = String(data: savedData, encoding: .utf8) {
let decoder = JSONDecoder()
let jsonData = contents.data(using: .utf8)
let config = try decoder.decode(FixtureConfig.self, from: jsonData!)
let address = "http://" + config.maze_address
NSLog("Using Maze Runner address: " + address)
return address
}
}
catch let error as NSError {
NSLog("Failed to read fixture_config.json: \(error)")
}
NSLog("Waiting for fixture_config.json to appear")
sleep(1)
}

NSLog("Unable to read from fixture_config.json, defaulting to BrowserStack environment")
return bsAddress;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@ private Configuration createConfiguration(ReadableMap options) {
Configuration config = new Configuration(options.getString("apiKey"));
config.setAutoTrackSessions(options.getBoolean("autoTrackSessions"));

if (options.hasKey("endpoint")) {
config.setEndpoints(new EndpointConfiguration(options.getString("endpoint"), options.getString("endpoint")));
}
else if (options.hasKey("endpoints")) {
if (options.hasKey("endpoints")) {
ReadableMap endpoints = options.getMap("endpoints");
config.setEndpoints(new EndpointConfiguration(endpoints.getString("notify"), endpoints.getString("sessions")));
} else {
ConfigFileReader configReader = new ConfigFileReader();
String mazeAddress = configReader.getMazeRunnerAddress(reactContext);
String notifyEndpoint = "http://" + mazeAddress + "/notify";
String sessionEndpoint = "http://" + mazeAddress + "/sessions";
config.setEndpoints(new EndpointConfiguration(notifyEndpoint, sessionEndpoint));
}

if (options.hasKey("appVersion")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.reactnative.module

import android.content.Context
import android.util.Log
import org.json.JSONObject
import java.io.File
import java.io.IOException

const val CONFIG_FILE_TIMEOUT = 5000

class ConfigFileReader {

fun getMazeRunnerAddress(context: Context): String {
val externalFilesDir = context.getExternalFilesDir(null)
val configFile = File(externalFilesDir, "fixture_config.json")
var mazeAddress: String? = null
Log.i("Bugsnag", "Attempting to read Maze Runner address from config file ${configFile.path}")

// Poll for the fixture config file
val pollEnd = System.currentTimeMillis() + CONFIG_FILE_TIMEOUT
while (System.currentTimeMillis() < pollEnd) {
if (configFile.exists()) {
val fileContents = configFile.readText()
val fixtureConfig = runCatching { JSONObject(fileContents) }.getOrNull()
mazeAddress = getStringSafely(fixtureConfig, "maze_address")
if (!mazeAddress.isNullOrBlank()) {
Log.i("Bugsnag", "Maze Runner address set from config file: $mazeAddress")
break
}
}

Thread.sleep(250)
}
if (mazeAddress.isNullOrBlank()) {
Log.i("Bugsnag", "Failed to read Maze Runner address from config file, reverting to legacy address")
mazeAddress = "bs-local.com:9339"
}
return mazeAddress
}

private fun getStringSafely(jsonObject: JSONObject?, key: String): String {
return jsonObject?.optString(key) ?: ""
}

}

0 comments on commit b538576

Please sign in to comment.