diff --git a/.circleci/config.yml b/.circleci/config.yml index 91c281e7118..6746f8e7bf0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2 jobs: build: docker: - - image: circleci/node:12 + - image: circleci/node:12-browsers steps: - checkout - run: diff --git a/packages/opentelemetry-core/karma.conf.js b/packages/opentelemetry-core/karma.conf.js new file mode 100644 index 00000000000..4066eae7cd3 --- /dev/null +++ b/packages/opentelemetry-core/karma.conf.js @@ -0,0 +1,31 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const webpackConfig = require('./webpack/test.config.js'); + +module.exports = (config) => { + config.set({ + listenAddress: 'localhost', + hostname: 'localhost', + browsers: ['ChromeHeadless'], + frameworks: ['mocha'], + reporters: ['spec'], + files: ['test/index-webpack.ts'], + preprocessors: {'test/index-webpack.ts': ['webpack']}, + webpack: webpackConfig, + webpackMiddleware: {noInfo: true}, + }); +}; diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index 2be955b0051..dff2afcad55 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -3,11 +3,18 @@ "version": "0.0.1", "description": "OpenTelemetry Core", "main": "build/src/index.js", + "browser": { + "./src/platform/index.ts": "./src/platform/browser/index.ts" + }, "types": "build/src/index.d.ts", "repository": "open-telemetry/opentelemetry-js", "scripts": { - "test": "nyc ts-mocha -p tsconfig.json test/**/*.ts", - "tdd": "yarn test -- --watch-extensions ts --watch", + "test": "yarn test:node && yarn test:browser", + "test:node": "nyc ts-mocha -p tsconfig.json test/**/*.ts", + "test:browser": "karma start --single-run", + "tdd": "yarn tdd:node", + "tdd:node": "yarn test -- --watch-extensions ts --watch", + "tdd:browser": "karma start", "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", "clean": "rimraf build/*", "check": "gts check", @@ -40,9 +47,13 @@ ".ts" ], "exclude": [ - "src/index.ts", "**/*.d.ts", - "build/**/**/*.js" + "build/**/**/*.js", + "karma.conf.js", + "src/index.ts", + "src/platform/browser/*.ts", + "test/index-webpack.ts", + "webpack/*.js" ], "all": true }, @@ -52,12 +63,20 @@ "devDependencies": { "@types/mocha": "^5.2.5", "@types/node": "^10.12.12", + "@types/webpack-env": "1.13.9", "codecov": "^3.1.0", "gts": "^1.0.0", + "karma": "^4.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^4.0.2", "mocha": "^6.1.0", "nyc": "^14.0.0", + "ts-loader": "^6.0.4", "ts-mocha": "^6.0.0", "ts-node": "^8.0.0", + "webpack": "^4.35.2", "typescript": "^3.4.5" }, "dependencies": { diff --git a/packages/opentelemetry-core/src/platform/browser/id.ts b/packages/opentelemetry-core/src/platform/browser/id.ts new file mode 100644 index 00000000000..11038e010f6 --- /dev/null +++ b/packages/opentelemetry-core/src/platform/browser/id.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// IE 11 exposes `crypto` as `msCrypto`. +declare type WindowWithMsCrypto = Window & { + msCrypto?: Crypto; +}; +const cryptoLib = window.crypto || (window as WindowWithMsCrypto).msCrypto; + +const SPAN_ID_BYTES = 8; +const spanBytesArray = new Uint8Array(SPAN_ID_BYTES); + +/** Returns a random 16-byte trace ID formatted as a 32-char hex string. */ +export function randomTraceId(): string { + return randomSpanId() + randomSpanId(); +} + +/** Returns a random 8-byte span ID formatted as a 16-char hex string. */ +export function randomSpanId(): string { + let spanId = ''; + cryptoLib.getRandomValues(spanBytesArray); + for (let i = 0; i < SPAN_ID_BYTES; i++) { + const hexStr = spanBytesArray[i].toString(16); + + // Zero pad bytes whose hex values are single digit. + if (hexStr.length === 1) spanId += '0'; + + spanId += hexStr; + } + return spanId; +} diff --git a/packages/opentelemetry-core/src/platform/browser/index.ts b/packages/opentelemetry-core/src/platform/browser/index.ts new file mode 100644 index 00000000000..048ff30c5a7 --- /dev/null +++ b/packages/opentelemetry-core/src/platform/browser/index.ts @@ -0,0 +1,17 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './id'; diff --git a/packages/opentelemetry-core/src/platform/index.ts b/packages/opentelemetry-core/src/platform/index.ts new file mode 100644 index 00000000000..7a0ffcb5018 --- /dev/null +++ b/packages/opentelemetry-core/src/platform/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Use the node platform by default. The "browser" field of package.json is used +// to override this file to use `./browser/index.ts` when packaged with +// webpack, Rollup, etc. +export * from './node'; diff --git a/packages/opentelemetry-core/src/common/util/id.ts b/packages/opentelemetry-core/src/platform/node/id.ts similarity index 100% rename from packages/opentelemetry-core/src/common/util/id.ts rename to packages/opentelemetry-core/src/platform/node/id.ts diff --git a/packages/opentelemetry-core/src/platform/node/index.ts b/packages/opentelemetry-core/src/platform/node/index.ts new file mode 100644 index 00000000000..048ff30c5a7 --- /dev/null +++ b/packages/opentelemetry-core/src/platform/node/index.ts @@ -0,0 +1,17 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './id'; diff --git a/packages/opentelemetry-core/test/index-webpack.ts b/packages/opentelemetry-core/test/index-webpack.ts new file mode 100644 index 00000000000..a1b2c077f62 --- /dev/null +++ b/packages/opentelemetry-core/test/index-webpack.ts @@ -0,0 +1,20 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file is the webpack entry point for the browser Karma tests. It requires +// all modules ending in "test" from the current folder and all its subfolders. +const testsContext = require.context('.', true, /test$/); +testsContext.keys().forEach(testsContext); diff --git a/packages/opentelemetry-core/test/common/util.id.test.ts b/packages/opentelemetry-core/test/platform/id.test.ts similarity index 93% rename from packages/opentelemetry-core/test/common/util.id.test.ts rename to packages/opentelemetry-core/test/platform/id.test.ts index bfaec6e74e3..a38aec7b4ec 100644 --- a/packages/opentelemetry-core/test/common/util.id.test.ts +++ b/packages/opentelemetry-core/test/platform/id.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { randomSpanId, randomTraceId } from '../../src/common/util/id'; +import { randomSpanId, randomTraceId } from '../../src/platform'; describe('randomTraceId', () => { it('returns different 32-char hex strings', () => { diff --git a/packages/opentelemetry-core/webpack/test.config.js b/packages/opentelemetry-core/webpack/test.config.js new file mode 100644 index 00000000000..1a3ef4e3086 --- /dev/null +++ b/packages/opentelemetry-core/webpack/test.config.js @@ -0,0 +1,86 @@ +/** + * Copyright 2019, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This is the webpack configuration for browesr Karma tests. +module.exports = { + mode: 'development', + output: {filename: 'bundle.js'}, + resolve: {extensions: ['.ts', '.js']}, + devtool: 'inline-source-map', + module: { + rules: [ + {test: /\.ts$/, use: 'ts-loader'}, + { + parser: { + // This setting configures Node polyfills for the browser that will be + // added to the webpack bundle for Karma tests. + node: { + // Enable the assert library polyfill because that is used in tests + assert: true, + // The assert polyfill from github.com/browserify/commonjs-assert + // also requires the `global` polyfill. + global: true, + + // Turn off all other Node.js API polyfills for the browser tests to + // make sure that we are not attempting to use Node-specific APIs in + // the browser code. Instead, we will write browser specific + // implementations of platform functionality we need under the + // `./src/platform/browser` folder. This allows for writing browser + // optimized implementations of the specific needed functionality + // rather than bringing in (sometimes large) polyfills for the + // corresponding Node APIs. + Buffer: false, + __dirname: false, + __filename: false, + buffer: false, + child_process: false, + cluster: false, + console: false, + constants: false, + crypto: false, + dgram: false, + dns: false, + domain: false, + events: false, + fs: false, + http: false, + https: false, + module: false, + net: false, + os: false, + path: false, + process: false, + punycode: false, + querystring: false, + readline: false, + repl: false, + setImmediate: false, + stream: false, + string_decoder: false, + sys: false, + timers: false, + tls: false, + tty: false, + url: false, + util: false, + vm: false, + zlib: false, + }, + }, + }, + ], + }, +};